,--»'•
'^/inn n \\
Mi \\ \\ \\
$19.95
. , ~.^.^E^i^^^yg«»*^
■- ^'„w^^nj..-V>-ti'/^-j5ii
f w-VSftS- -*-*Vycy>. «
;«Xfc^'li»*^^<''S»^'***'«*^
-iV-^y^
: INSIDE ATARI DOS
<_
From The Editor's of COMPUTE! Magazine and
Optimized Systems Software, inc.
INSIDE
ATARI DOS
Compiled by Bill Wilkinson,
Optimized Systems Software, Inc.
Published by COMPUTE! Books,
A Division of Small System Services, Inc.,
Greensboro, North Carolina
ATARI is o registered trademark of Atari, Inc.
Preface
This book contains the only complete and official listings for the disk
File Manager System (FMS) commonly known as "Atari DOS 2. OS."
You will note that we have clearly stated that the purchase of this
book does not entitle you to make, sell, give, or otherwise distribute
copies of either the original Atari DOS 2. OS or any modified version
you may produce as a result of using this book.
By way of information, should you desire to produce and distribute
a modified version of this product (e.g., to support a new disk drive),
you must sign a contract and licensing agreement with the party who
owns the rights to grant such licenses for non-exclusive uses. Currently,
Optimized Systems Software is the only entity able to grant such
licenses.
Some of you may find it strange that the publishers of COMPUTE!
mai'azine are publishing this book. You might wonder why Atari,
Inc. , hasn't released this information before. Why can you only obtain
distribution rights from Optimized Systems Software? For the answers
to these and other questions we present the following Introduction,
an Inistorical perspective on the development of the systems software
for the Atari Home Computers.
All reasonable care has been taken in the writing, testing, and correcting of the text and of the
sottv'are within this book. There is, however, no expressed or implied warranty of any kind fVom
the authors or pubUshers with respect to the text or software herein contained. In the event of
any damages resulting from the use of the text or the software in this book, the authors or
publishers shall be m no sense liable. Please review the important cautions noted in Appendix A
regarding the use of this book.
Copvright © 1982 text. Small System Services, Inc.
Copyright © 1978, 1979, 1980, 1982 program listings. Optimized Systems Software, Inc.
AH rights reserved. Reproduction or translation of any part of this work beyond that permitted
by sections 1 07 and 1 08 of the United States Copyright Act without the permission of the '
copyright owner is unlawful.
Printed in the United States of America
ISBM 0-942386-02-7
10 98765432
Table of Contents
Preface Page ii
Introduction; Being a History of Two Births: "Coleen" and "Candy" Page iv
Chapter One: Atari DOS Overview Page 1
Chapter Two: Disk Organization Page 10
Chapter Three: FMS File Control Blocks (FOB) Page 15
Chapter Four: FMS Initialization Page 17
Chapter Five: FMS Entry Page 22
Chapter Six: FMS Exit Page 23
Chapter Seven: Device Dependent Commands Page 25
Chapter Eight: FMS Open Routines Page 3 1
Chapter Nine: FMS Close Routines Page 34
Chapter Ten: The GET BYTE Routine Page 36
Chapter Eleven: The PUT BYTE Routine Page 37
Chapter Tweh^e: Burst I/O Page 38
Chapter Thirteen: Reading the Directory as a File Page 40
Chapter Fourteen: Sector I/O Routines Page 42
Chapter Fifteen: File Name Decode Routine Page 46
Chapter Sixteen: Directory Searching Page 48
Chapter Seventeen: Write Next Sector Page 50
Chapter Eighteen: Read Next Sector Page 51
Chapter Nineteen: Get and Free Sector Routines Page 53
Chapter Twenty: The Boot Process Page 55
Chapter Twenty-One: Maintaining the Boot Record Page 57
Atari DOS 2. OS Page 59
Appendix A: An Intermediate User's Guide To This Book .... Page 102
COMPUTE! Books is a division of Small System Services, Inc.,
Puhlisliers of COMPUTE! Magazine
Editorial Offices are located at:
625 Fulton Street, Greensboro, NC 27403 USA. (919)275-9809
Optimized Systems Software, Inc. , is located at:
10379 Lansdale Avenue, Cupertino, CA 95014 USA. (408)446-3099.
Introduction
BEING A
HISTORY OF
TWO BIRTHS
"COLEEN"
AND
"CANDY"
I don't know exactly when the concept of the Atari Computer was
developed within the corporate mind of Atari, Inc., nor do I know all
of the people responsible for nursing that concept into reality. The
following history covers the relationship with Atari, Inc., during the
evolution of the system software.
Sometime in early 1978, when the Atari 800 and 400 were still
called "Coleen" and "Candy" and were still in the breadboard stages.
Atari bought a copy of the source for Microsoft 8K BASIC. This
version of BASIC was fundamentally the same product that was
implemented by Commodore in the early PETs, was used by OSI, and
was a close ancestor of Applesoft. Six months and many, many Atari
man-hours later, that 8K BASIC was almost functioning properly on
the Atari prototypes. But buying source for a program buys you just
that: source. Generally, you also receive little documentation,
sometimes obscure code, no guide to modification, and no real support.
What to do? The products were due to be shown in early January,
1979, at the Consumer Electronics Show (CES) in Las Vegas,
Nevada.
Enter Shepardson Microsystems, Inc. (SMI), my employer at
that time. Though little known by the microcomputer pukic, SMI
had already produced some very successful, private labeled
microcomputer software. Among our better-known efforts were the
original Apple DOS, Cromemco 16K Extended BASIC, and
Cromemco 32K Structured BASIC (just being completed at that
time). Also, we had done some work for Atari on a custom game
processor. (Which used a 12-bit ROM and 5-bit RAM configuration
and was well received at Atari, but never produced.)
Coincidentally, about that same time SMI had also purchased
source for Microsoft 6502 BASIC. After producing Apple's DOS, we
had the bright idea of mating the Apple II peripheral bus with the
KIM/SYM/AIM system bus (and it still seems like a good idea to us,
but ...). The idea was to provide a disk system (Apple's) to the Single
Board Computer market. Needing a BASIC to sell with the system,
we plunked down a few grand and purchased Microsoft's. Though it
looked to us like it would be difficult to modify, we were intending to
resell it with a minimum of changes, so it seemed appropriate.
A New BASIC?
Re-enter Atari, some time in the late summer of 1978, asking if SMI
could help them. With Microsoft BASIC? Well ... we really didn't
want to, but ... Could we propose a new BASIC? We talked. And
had meetings, and a study contract, and more meetings, and finally
we wrote a specification for a lOK, ROM-based BASIC. (I still have a
copy of that spec, and it's amazing how little the final version deviated
from that original.)
Of course, in the middle of all these discussions, Atari naturally
divulged how their (truly superb) ROM-based Operating System
would interface both with BASIC and with various devices.
Somewhere in here, my memory of the sequence of events and
discussions becomes a little unclear, but suffice it to say that we found
ourselves making a bid on producing not only a BASIC for Atari, but
also the File Manager (disk device driver) which would change Atari
OS to Atari DOS.
Sometime in late September, 1978, the final proposal was made
to Atari, and it was accepted by them shortly thereafter. In mid-
October, 1978, we received the go-ahead. The project leader was Paul
Laughton, author of Apple DOS. The bulk of the work ended up
being done by Paul and Kathleen O'Brien. Though I was still involved
in the finishing touches on Cromemco BAcSIC, I take credit for
designing the floating point scheme used in Atari BASIC. Paul Krasno
implemented the math library routines following guidelines supplied
to us by Fred Ruckdeschel (author of the acclaimed text, BASIC
Scientific Subroutines). And, of course, much credit must go to Mike
Peters, our combination keypuncher/computer operator/junior
programmer/troubleshooter.
Since we obviously couldn't have the Atari machines to work on
(they hadn't been built yet), the first step was to bring up an emulator
for Atari's CIO ("Central Input-Output," the true heart of Atari's
OS) on our Apple II systems. With Paul Laughton leading the way
(and doing a lion's share of the work), the pieces fell together quickly.
"Little" things had to be overcome: the cross-assembler was modified
to handle the syntax table pseudo-ops, the 256-byte Apple disk sectors
had to be made to look like 128-byte Atari sectors, the BASIC
interpreter seemed to function, but was waiting for the floating point
routines. And there are funny things to tell of, also. Like our cross-
assembler, running on an IMP-16P (a 1973 vintage, 16-bit, bit-sliced
PMOS microprocessor) that used keypunched cards for input, a floppy
disk (with no DOS) as temporary storage, and a paper tape punch as
output.
Somehow, Kathleen and Paul guided the two programs unerringly
toward completion. On December 28, 1978, Atari's purchasing
dej^artment at last delivered a signed copy of the final purchase order.
It called for delivery of both products by April 6, 1979. There was a
clause which provided for a $1,000 per week incentive (if we finished
early) and penalty (if we finished late). What is especially humorous
about that December 28th date is that the first working versions of
both BASIC and FMS had already been delivered to Atari over a week
before! That is fast work.
Fortunately, then. Atari took their new Atari BASIC to CES.
Unfortunately, there was a limit on the amount of incentive money
collectible. Oh, well.
In the months that followed, SMI fixed bugs, proofread manuals,
and worked on other projects (including the Atari Assembler/Editor,
which was mostly Kathleen's effort). The nastiest bugs in BASIC were
fixed by December, 1979, but it was too late: Atari had already
ordered tens of thousands of BASIC ROMs. The FMS bugs were
easier to get fixed, since DOS is distributed on disk.
In mid- 1980, Paul Laughton once again tore into FMS. This
tiir.e, he modified it to handle the ill-fated 815 double-density disk
drive and added "burst I/O" (and there will be much more about both
these subjects in the technical discussion that follows).
In late 1980, and early 1981, Bob Shepardson, owner of
Shepardson Microsystems, Inc. , decided that the pain and trouble of
having employees wasn't justified by the amount of extra income (if
any) that he derived. Though we still occasionally function in a loose,
cooperative arrangement, the halcyon days of SMI seem to be over.
A New Beginning
I negotiated with Bob Shepardson for his rights to the Atari products
(FMS, BASIC, and the Assembler/Editor) and their Apple II
counterparts. Thankfully, Atari had purchased from SMI only a non-
exclusive right to distribute these products. SMI had retained the
rights to license other users on a similar non-exclusive basis (and,
indeed, SMI sold a version for the Apple II during most of 1980).
So now it was frantic time again: this was February 25, 1981, and
the West Coast Computer Faire was April 3rd. But our brand new
company. Optimized Systems Software, arrived on time, bringing
with it BASIC A+ , OS/A+ and EASMD. All three were enhanced,
disk-based versions of the original Atari programs (and, in fact, derived
some of their enhancements from the previous OSS Apple II
products) .
The products have been well received by the Atari user
community, in part due to the fact that they are truly compatible, yet
enhanced, versions of standard Atari software.
Wily This Booic?
The decision to publish these listings was not an easy one to make;
and it is, in its own way, an historic occasion. After all, have you ever
seen anyone offering source or listings of CP/M, the most popular of
all computer operating systems? Since Atari, to their credit, has
hcinored the original agreement with SMI and not released either
source or listings without permission, the responsibility for doing so
seemed to rest with OSS.
But Atari has set a powerful precedent by publishing the listings
of DUP (their portion of DOS 2. OS) and the OS ROMs. The clamor
from Atari users for the source for FMS finally even reached us, so we
hsve bowed to the inevitable, and honored the same commitment
that Atari has made: to release as much information and aid as possible
to the user community.
We hope that the users will appreciate these efforts and, in turn,
respect our rights and Copyrights. As long as there is a mutual respect
and benefit, you, the user, can expect continued support.
AI>out Ihis Booic
^X'ith the release of this book, the dedicated Atari enthusiast can
e>:amine all the inner workings of Atari DOS and modify his (or her)
system to his heart's delight. Rather than simply publish listings, we
have chosen also to provide a complete guide to the workings of FMS.
Although the listing itself is relatively clear and commented, all
but the most expert would have trouble plowing through some of the
toniuous logic necessary in such a program. The guide included here
describes all aspects of the FMS, including the external view, the
chsitts and tables, the various interfaces, and (in copious detail) the
functions of the individual subroutines (including complete entry and
exit parameters).
There is much of value here even for the person who never
intends to modify Atari DOS. We feel that FMS is a fairly well-
structured, relatively sophisticated, system level assembly language
program. We hope that most users will gain by the insights presented
here.
We would welcome any notes you would care to send pointing
out errors either in the DOS or in this book.
Bill Wilkinson
Optimized Systems Software
Cupertino, California
February, 1982
Chapter One
ATARI
OVERVIEW
The standard Atari Disk Operating System, DOS 2.08, consists of
four separate elements, ranked as follows in order of their "visibility"
to the average DOS user.
1. DUP - Disk Utility Package
2. CIO - Central Input/Output
3. FMS — File Management System
4. SIO - Serial Input/Output
It is helpful to understand the entire Input/Output (I/O) process.
While this book is intended to give detailed information on the
workings of FMS, this overview will attempt to at least show how the
four elements of DOS are connected. To this end, we would first call
your attention to Figure 1. This figure is, itself, an overview of the
entire Atari I/O system, including indications as to how and where
data and control flows between the various elements thereof. Figures
1-1 through 1-4 show "close-ups" of portions of this diagram as they
re .ate to the four elements of EXDS.
In these figures, the rectangular boxes represent system elements,
and are appropriately labeled. The wide, lettered arrows represent the
flow of data (via buffers, control blocks, or even registers) between
the various elements. The narrow, numbered arrows show how and
where control, and control information, is transferred.
1-1. Disk Utility Pacicage
DUP (which shows as "DUP. SYS" in a disk directory listing) is the
most obvious and visible element of Atari EXDS. DUP's function is to
provide the user with keyboard access to the various file management
functions in FMS. It does so via the menu which is displayed when,
for example, the user keys "DOS" from BASIC. Actually, the menu
offers several options which are not directly a part of the FMS (e.g. ,
copy and duplicate files). Refer to the Atari Disk Operating System U
CHAPTER ONE
Reference Manual (part number C016347) for more information.
DUP is not an integral part of FMS. DUP may be relatively easily
replaced with a program of the user's choice. In fact, our own OS/A +
does exactly that: instead of a menu, the user is given a command-
driven keyboard interface to the other elements of DOS.
DUP is not even a privileged portion of IX)S (excepting, perhaps,
for reeding to know a little of the internals of FMS when it performs a
Duplicate Disk function). Any user application program (and that
includes Atari BASIC, BASIC A + , EASMD, and many, many
more) interacts the same way DUP does. Figure 1-1 shows the "proper"
flow of control in EXDS. Note that DUP transfers control only to
CIO, which, in turn, transfers control to FMS and thence to SIO. An
application program which maintains this protocol should be able to
perform correctly in any Atari system, regardless of the revision of the
OS ROMs and/or FMS.
Of course, control is not the only thing which DUP must transfer.
It must also tell CIO where its data is and what to do with it. Refer to
Figure 1-2 for a diagram of the complete application/CIO interface
(again, it is labeled in this way because DUP is just another application
program as far as the rest of DOS is concerned). CIO always expects
an Input/Output Control Block (lOCB) and usually (i.e., for all but
the simplest operations) needs a buffer into or out of which it may
perform its operations.
1-2. Central Input/Output
CIO is actually the heart of the entire Atari Computer. It is less than
800 bytes long and yet serves to handle virtually all the input and
output which takes place in the computer. CIO is a part of the Atari
"OS ROMs," the I OK byte package which also houses the floating
point routines, the default character set, the interrupt handlers, and
several device drivers.
The entire set of operations summarized in Figure 1-2 is covered
in detail in the Atari OS Manual (C01655) and will be covered only
briefly here. Readers of COMPUTE! will also find some helpful material
on this subject in issues #18 through #21 (November, 1981, through
February, 1982) in the "INSIGHT: ATARI" columns.
In order to allow easy control and data flow, CIO is written to
expect and provide for eight Input/Output Control Blocks (lOCBs)
which are used to pass the information needed to process the various
kinds of I/O requests. An application places the necessary command
and control information in an lOCB which it selects (data path A). If
a buffer is required, the application must provide one (data path C)
CHAPTER ONE
and place its address into the lOCB. When ready to execute the I/O
command, the appUcation places the lOCB number (times 16) in the
6502's X-register (data path C) and executes a JSR call to CIO (control
path 1 ). Note that a few command variations may pass data via the
6502's A-register, but we may consider that simply a special case
location of the user's buffer.
When CIO receives control, it examines the information in the
lOCB (and, for some operations, in the user buffer) to determine
what actions it is to perform. Generally, this action requires the
execution of a device handler routine.
A device handler (interchangeably known as a device driver) is a
system routine that performs I/O operations for a specific device (or
class of devices). Examples of device handlers include the "P:" driver
(the printer) and the "E:" driver (the screen/keyboard editor). Figure
1-3 illustrates the interface between CIO and the various device
handlers. Note that FMS is simply another device handler as far as
CIO is concerned, having been given the name "D:".
All device drivers are required to contain a table of address pointers
(known as the Device Vector Table) to various specific routines
within themselves, including a device OPEN routine, GET
CHARACTER routine, etc. The name of a device and the address of
this table is placed in CIO's Device Handler Table. When an
application program makes an I/O request to CIO for a specific device,
CIO searches the Device Handler Table for the given name and
corresponding Device Vector Table address. With the thus-located
vector table, CIO can then call the appropriate device handler routine
(via a JSR, along control path two of Figure 1-3).
1-3. File Management System
As. stated above, FMS is actually simply another device driver as far as
CIO is concerned. The control and data flows shown in Figure 1-3 are
equally valid for all device drivers in the Atari system. Note that
many of the drivers in the default ("as-shipped") system reside entirely
within the so-called OS ROMs. Although it resides in RAM, what is
somewhat unique about FMS is that the Atari system initialization
code contains a segment of "boot" code which loads FMS into memory
upon power-on.
FMS is the system device handler for all I/O operations that
specify the device name "D" (including "Dl:", "D2:", etc.). In order
to perform its functions, FMS examines the data in the specified
ICCB (data path F). It may also examine, read, or write data to or
frcim the user-supplied buffer (data path I). Data path H is used to pass
CHAPTER ONE
the I(ZXZ!B-designator (again, via the X-register) and single-byte transfer
data (via the A-register).
FMS is called upon to perform a variety of tasks, including all
disk I/O, file renaming, protecting, deleting, etc. Since the rest of
this book consists of a listing of FMS along with detailed explanations
of all sections thereof, we will not now dwell on the inner workings of
FMS.
However, we do need to note that, in order to perform its work,
FMS must transfer data to and from the disk. FMS accesses the disk
drive via SIO, the fourth element of DOS.
1-4. Serial Input/Output
SIO is the name given to the component of DOS which drives and
controls the Atari serial I/O bus and the various peripherals (disk,
printer, modem, etc.) which are placed on that bus. Figure 1-4
illustrates the interface between FMS and SIO, but it could just as
well serve to show (for example) how the printer driver talks to the
various Atari printers.
The SIO is primarily driven by a request placed in SIO's Device
Control Block (DCB) by the device handler (data path K) followed
by a transfer of control (control path three) via a JSR. SIO uses the
information in the DCB (data path M) to determine what it needs to
do. If the EXHB specifies a serial bus data transfer (as opposed to, for
example, a status request), then the address of the data buffer must
also be passed (via a field in the DCB). For example, the FMS buffer
shown is accessed via data paths J (from FMS) and L (from SIO).
Although SIO only understands the single system DCB, the
buffer specified may be located anywhere in memory. FMS takes
advantage of this to implement "burst I/O" (discussed in section 12),
which has SIO transferring data directly to or from the user's buffer
(data path E).
Since the actual disk data transfer occurs in fact within the 810
disk drive and, since SIO communicates to the drive via data path N,
one might reasonably argue that the disk drive constitutes a fifth
component of DOS. However, because the disk drive functions are
preprogrammed in ROM, and because SIO implements the only
method of accessing the disk (as well as most other peripherals), then,
for all practical purposes, even machine language software may treat
SIO as the last link in the I/O chain on the Atari Computers.
Once again, we remind you to study Figure 1. In the following
dissertation and dissection of FMS, we shall refer to this chart often.
o
-1
■p o
So
O) o
Q
o
1^ 1^
.y DJOCL
<
Q
ox
X
o
1(3
CO
o
CO
CO
0)
o
D
0)
2 5
iz _0
D
<
SJ OiOol
112 I R
^ to >
3
Q.
O
5
0^:C>[
CO
A
CD 3 LI. U_ LXJ Oi
<X>
CO
ft
>
QOco
□3 3 i-L u_ Lu C^
A
coco
A
>[
■OUCD
<
(D
O
O
1=
i^-
CO ii
- ij
O £1
^-^^
"- CD
(J
>
(D
I
C)
C)
CD Z) U_ U_ LU Ci^
D g ^^
.y o) ocl
<
o>
<=>
QUm
A
-OUcQ
<I
^ « >
cob^
CD
O
D
|o
u.: CO
CO
3
a
-*—
3
o
c
D
O
<:^=>
QOoD
A
>
o 2 _
.y a>o a;
<
<x>
CD Z3 Ll_ u_ LU D;
<:>
<Z>
cU
>[
• oum
<0
A
Chapter Two
DISK
ORGANIZATION
The purpose of FMS is to organize the 720 data sectors available on an
810 (diskette into a system of named data files. FMS has three primary
data structures that it uses to organize the disk: the Volume Table of
Contents, the Directory, and Data Sectors. The Volume Table of
Concents is a single disk sector which keeps track of which disk sectors
are available for use in data files. The Directory consists of directory
sectors. It is used to associate file names with the location of the files'
sectors on the disk. Each Directory entry contains a file name, a
pointer to the first data sector in the file, and some miscellaneous
information. The Data sectors contain the actual data and some
control information that link one data sector to the next data sector
in the file. Figure 2-1 illustrates the relation between the Directory
and the Data files.
Disk Directory
The Directory starts at disk sector $169 and continues for eight
contiguous sectors, ending with sector $170. These sectors were
chos(m for the directory because they are in the center of the disk and
therefore have the minimum average seek time from any place else on
the disk. Each directory sector has space for eight file entries. Thus, it
is possible to have up to 64 files on one disk.
A Directory entry is 16 bytes in size, as illustrated by Figure 2-2.
The directory entry flag field gives specific status information about
the current entry. The directory count field is used to store the number
of sectors currently used by the file. The last eleven bytes of the entry
are the actual file name. The primary name is left justified in the
primary name field. The name extension is left justified in the extension
field. Unused filename characters are blanks ($20). The Start Sector
Number field points to the first sector of the data file.
Data Sectors
A Data Sector is used to contain the file's data bytes. Each 128 byte
data sector is organized to hold 125 bytes of data and three bytes of
10
CHAPTER TWO
control information as shown in Figure 2-3. The data bytes start with
the first byte (byte 0) in the sector and run contiguously up to, and
including, byte 124. The control information starts at byte 125.
The sector byte count is contained in byte 125. This value is the
actual number of data bytes in this particular sector. The value may
range from zero (no data) to 125 (a full sector). Any data sector in a
file may be a short sector (contain less than 125 data bytes).
The left six bits of byte 126 contain the file number of the file.
This number corresponds to the location of the file's entry in the
Directory. Directory entry zero in Directory sector $169 has the file
number of zero. Entry one in Directory sector $169 has the file number
one — and so forth. The file number value may range from zero to 63
($3F). The file number is used to insure that the sectors of one file do
not get mixed up with the sectors of another file.
The right two bits of byte 126 (and all eight bits of byte 127) are
used to point to the next data sector in the file. The ten bit number
contains the actual disk sector number of the next sector. Its value
ranges from zero to 719 ($2CF). If the value is zero, then there are no
more sectors in the file sector chain. The last sector in the file sector
chain is the End-Of-File sector. The End-Of-File sector may or may
not contain data, depending upon the value of the sector byte count
field.
Volume Table Of Contents (VTOC)
The VTOC sector is used to keep track of which disk sectors are
available for data file usage. The VTOC sector is located at sector
$16'8. Figure 2-4 illustrates the organization of the VTOC sector. The
most important part of the VTOC is the sector bit map.
The sector bit map is a contiguous string of 90 bytes, each of
which contains eight bits. There are a total of 720 (90 x 8) bits in the
bit map - one for each possible sector on an 810 diskette. The 90
bytes of bit map start at VTOC byte ten ($0A). The leftmost bit ($80
bit) of byte $0A represents sector zero. The bit just to the right of the
leftmost bit ($40 bit) represents sector one. The rightmost bit (bit
$01 ) of byte $63 represents sector 719.
The fact that EMS interprets the bit map as representing sectors
zero through 719 is a bug. The Atari 810 disk drive will not accept
commands for sector zero. It will accept commands for sector 720. In
other words, the bit map is skewed by one. The problem cannot be
fix€:d now because there are already tens of thousands of diskettes
whose bit maps are to be interpreted as representing sectors zero through
719, and because some savvy applications writers have taken advantage
11
CFUVPTER TWO
of this feature. (A bug which generates useful side effects is known in
the programming profession as a feature. ) Sector 720 can never be
use(i by FMS and is therefore available for miscellaneous purposes.
Directory Sectors
Sector $169 -
Figure 2-1
12
CHAPTER TWO
Typical Directory Sector
Er^tryO
Entry!
Entry 2
Entry 3
Entry 4
Entry 5
Entry 6
Entry?
Typical Directory Entry
1
13
Count
SSN
Primary Nome
Extension
Start Sector Number (Low, Higti)
The Sector Number of ttie First
Sector in the File Sector Chain
Count (Low, High)
The Number of Sectors in the File
Flag
$00 - Entry Has Never Been Used
$80 - Entry Has Been Deleted
$40 - Entry In Use
$20 - Entry Locked
$02 - File Created By DOS 2
$01 - File Opened For Output
Figure 2-2
13
CHAPTER TWO
Typical Data Sector
Data
125 Bytes
Control
Byt€i 125
Byt6i 126
Byt€i 127
1 \-^
j
■r
V ^
1 • k-^
Number Bytes Used In Sector (0-125)
Next Sector Number (Might Two Bits]
File Number (0-63)
Next Sector Number (Low Eight Bits)
Figur€J 2-3
VrOC Sector ($168)
0-9
Misc. info.
$0A-$63
Sector Usage
Bit Map
$64-$7F
Unused
1
3
5
6
1 1 1
Type Code ( = in DOS 2.0)
Number Sectors Total ($2C3)
Number Unused Sectors
Reserved
Unused
- Eacti bit represents a specific sector
- Thie left most bit ($80) of byte $0A is sector number (does not exist)
- Thie next bit ($40) of byte $0A is sector number 1
- The right most bit ($01) of byte $63 is sector number $719.
- If the bit is one, the sector is unused and available
- If the bit is off (zero), the sector is used
Figure 2-4
14
Chapter Three
FMS
FILE CONTROL
BLOCKS
(FOB)
The FMS File Control Blocks are used to store information about files
that are currently being processed. Each file that is being processed
concurrently by FMS requires one FCB. Since the Atari system has
eight lOCB's, FMS must be prepared to handle up to eight files
concurrently, thus there are eight FCBs. The FCBs were designed to
have a one-to-one correspondence with the lOCBs. When a file is to
be processed with ICXI^B number three, FMS will use FCB number
three for that file. When a file is to be processed with lOCB number
five, FMS will use FCB number five for that file. Each FCB is the
same size as an lOCB (16 bytes). The FCBs are located in a contiguous
RjKM area just like the lOCBs. When CIO calls FMS, the X register
contains the displacement (ICXDB number times 16) to the lOCB
making the request. The FMS uses this displacement value to access
both the lOCB information and the FCB information. Please refer to
the listing at location $1381 for the following discussion about the
fc:bs.
FCBFNO
The file number of the file currently being processed. The value (zero
to 63) is shifted left two bits. When a file has been opened for reading,
this value will be used to check for a file number mismatch in the data
se<:tors. When a file is opened for write, this value will be placed in
the file number field of the data sectors.
FCBOTC
0]3en Type Code. This value is used as a flag to indicate which mode
the file has been opened for:
Input is $04.
15
CHAPTER THREE
Output is $08.
Update is $0C.
Append is $01.
Directory read is $02.
FCBSLT
This is a tlag used to indicate that the file being processed was created
by EOS 1 rather than OOS 2. The Data Sector length byte has a
different interpretation under DOS 1 .
FCBFLG
This field is a working flag. If the value is $80, then the file is eligible
to ac:quire new data sectors. Files that are opened for Output or Append
are e'ligible to acquire new data sectors. If the value is $40, then the
sector currently is in a memory buffer, has been modified, and needs
to b<; written back to the disk.
FC»MNL
If the file is opened for Output or Append, this value will be either
125 or 253 depending upon the drive type. The 253 value is meant for
the i\tari 815 dual density drive. If the file is opened for Read or
Update, then this value represents the number of data bytes that are
in the data sector currently in a buffer. This value is obtained from the
Data Sector data length field (byte 125 of the data sector.)
FCBDLN
This value points to the next data byte to be operated on in a data
sector. If the file is opened for Output or Append, this value points to
the next available (unused) data byte in the current data sector. If the
file is opened for Update, then this value points to the next data
sector byte to be either read or modified. If the file is opened for
Inptit, then this value points to the next byte to be read.
FCBBUF
This value is an index into the sector buffer table. The sector buffer
table is a list of buffer addresses. When a file is being processed, a
sector buffer is required to hold data sectors. This field tells FMS
which FMS buffer has been allocated to the file.
FCBCSN
The sector number of the sector currently in the buffer is stored in this
field.
16
FCBLSN
The sector number of the next sector in the file chain is stored in this
field.
FCBSSN
If the file has been Opened for Append, then this field contains the
sector number of the start of the sectors to be appended to the file
when the append file is closed.
Chapter Four
FMS
INITIALIZATION
DUP gets control whenever the system is booted or the RESET key is
pressed. DUP will call the FMS initialization routine, DINIT at $7E0.
DINIT
Functions:
1) Determine how many (and what type of) disk drives will be
used.
2) Set up a drive table and allocate a drive buffer for each drive.
3) Allocate sector buffers and build the sector buffer table.
4) Clear the FCBs to zero.
5) Set MEMLO.
6) Enter the D: device into the Device Handler Table.
7) Exit to caller via RTS.
Drive Determination
Th<; DRVBYT byte at $70A is used to tell FMS how many disk drives
will be used and what the drive number of the drives will be. The
17
CHAPTER FOUR
rightmost bit (bit $01) indicates drive 1. The next left bit ($02)
indicated drive 2 - and so forth. If the bit is one, then the drive is to
be used. If the drive is zero then the drive is not to be used. The code
will allocate up the eight drives, even though the 810 hardware only
has switches for drives 1,2,3 and 4.
If DRVBYT indicates that a drive is to be used, then FMS issues
a status command to that drive to determine if it is active and what
type (810 or 815) of drive it is.
Drive Allocations
The drive determination process sets up two tables (Figure 4-1). The
first table is the DRVTBL. This table is indexed into by the drive
number (minus one). If the value in the table is zero then the drive is
not to be used. If the value is one, then the drive is an active 810 and
requires one drive buffer. If the value is two, then the drive is an 815
and requires two 128 byte buffers.
The second table is the drive buffer table. The drive buffer table
contains the address of the drive buffer to be used for each drive. This
Drive Buffer will be used to hold the VTOC sector on the diskette in
the drive. The table is separated into two sections: DBUFAL contains
the least significant address byte and DBUFAH which contains the
most significant address byte. The drive buffer table is also accessed by
the drive number (minus one).
When a file is being processed, the Drive number is obtained
froiTi the lOCB Device Number field, ICDNO. The obtained value is
decxemented by one and is then used as an index into the Drive Tables.
The Drive Type is copied from the DRVTBL entry to DRVTYP
($1 2FE) for easy access by FMS. The Drive Buffer address is copied
from the DBUFAL and DBUFAH table entries to the zero page drive
buffer pointer, ZDRVA ($45).
Sector Buffer Allocations
The SABYTE at location $709 is used to inform FMS about the
number of 128 areas to be allocated as sector buffers. One 128 buffer is
required for each file which is to be processed concurrently on 810
drives. Two 128 byte buffers are required for each file which is to be
processed concurrently on 815 drives.
The Sector Buffer Allocation table, SECTBL at $1319, is used to
indicate if a buffer is available for allocation to a file (Figure 4-2). If a
buffer is available, the entry is set to zero. If the buffer is not available,
the entry is a minus value. The table is 16 bytes in size and therefore
cari be used to allocate up to sixteen 128 byte buffers. During the
18
CHAPTER FOUR
initialization process, entries which are to be unused are set to a minus
value.
The Sector Buffer Address Table is a table of addresses which
point to the individual sector buffers. The table is divided into two
parts: SABUFL contains the least significant address byte, SABUFH
contains the most significant address byte.
When a file is being processed, an available buffer number is
found in SECTBL by search for a zero valued entry. The located
buffer is allocated to the file by entering a minus value ($80) into the
table and placing the corresponding buffer number into the DCB
buffer number field, FCBBUF. When the file processing is done, the
buffer is deallocated by setting the SECTBL entry to zero.
Setting MEMLO
The Atari MEMLO location ($2E7) is set after the FMS buffers have
be4;n allocated. The address of the last sector buffer allocated is
incremented by 128. This value is then placed into MEMLO.
Dcivice Handler Table Entry
The Device Handler Table ($31 A) is searched for a "D" entry or the
first (from the top) empty entry. When an appropriate entry is found,
FVIS inserts (or reenters) "D" as a DEVICE NAME and sets the
DEVICE vector entry to point to the FMS Device Vector table at
DFMSDH ($7CB).
19
CHAPTER FOUR
$70A DRVBYT .BYTE $0F ; Allocates Drive 1,2,3,4
i
Drive Bits
r
1111
S1311 DRVTBL
• + 9
Drive Table
3
Drive No.
Index
1
2
1
-••3
2
4
3
5
4
6
5
7
6
8
7
1
1
2
2
Drive Type From Status
810 Drive -m
810 Drive •«
815 Drive -•
815 Drive ■•
No Drive
No Drive
No Drive
No Drive
[1;1329 DBUFAL
• + 8 : Drive Butter Address Table (Lov>/) |
Oi
1331 DBUFAH
• + 8 : Drive Butter Address Table (High)
Q:
70C SASA
.WORD
$1A7C : Butter Start Address
Dr ive No.
1
2
-••3
4
5
6
7
Index
~0~
1
2
3
4
5
6
7
DBUFAH
DBUFAL
1A
1A
a
7C
FC
IB
7C
1C
7C
00
00
00
00
00
00
00
00
128 Byte Butter For Drive 1 At S1A7C
256 Byte Butter For Drive 3 At $1B7C
Figure 4-1
Drive Tables
20
CHAPTER FOUR
$1319 SECTBL
• + 16 ; Sector Allocation Table
Buffer Number
00
Buffer Is Available
1
00
2
00
3
00
00
00
5
6
00
Buffer Is Available
7
FF
Buffer NOT Available
8
FE
9
FD
10
FC
11
FB
12
FA
13
F9
14
F8
15
F7
16
F6
Buffer NOT Available
!;709 SABYTE BYTE
7 : Number Of 128 Byte Sector Buffers
S1339 SABUFL
• + 16 ; Sector Buffer Address (Low) Table
!)1349 SABUFH
• + 16 ; Sector Buffer Address (High) Table
(Last Drive Buffer Address + Dri\
/e Type (1 or 2) • 128)
^
Buffer Number SABUFL SABUFH
1C
8C
•• ■'
1
1D
OC
(Previous Entry + 128)
2
ID
8C
3
IE
1E
OC
80
Sector Buffer 4 Address = $1E80
5
IF
OC
6
IF
80
7
20
OC
8
GO
00
9
00
00
10
00
00
11
00
00
12
00
00
13
00
00
14
00
00
15
00
00
Figure 4-2
Sector Allocation Tables
21
Chapter Five
FMS
ENTRY
The Device Vector Table for FMS is located at DFMSDH ($7CB).
The address of this table is placed in the Device Handler Table by the
FMS Initialization routine. When CIO needs to call an FMS function
(Figure 1, control path 2), it will locate the address of the function via
the' table at DFMSDH. This table is the standard Atari Device Handler
Vector Table. The six entries are for:
Open
Close
Get Byte
Put Byte
Status
Device Dependent (XIO) Commands
Each of the six FMS entry points starts with a subroutine call to
the FMS SETUP routine. SETUP ($1164) prepares FMS parameters
to deal with the particular task to be performed.
SErup
Address -$1164
Entry Registers - A = Possible 'Put Data' data byte.
X = lOCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = lOCB number times 16.
Y = Sector Buffer Index.
Functions:
1) Initialize ERRNO to $9F. This value will be used in the FMS
exit routines to form a FMS error number in the event of error.
2) Save the X Register in CURFCB. This value will be used as
an index to the proper lOCB and the proper FCB for the current
operation.
3) Save the value of the stack register as it was upon entry to
22
FMS. This value will be used in the FMS exit routine.
4) Set up drive information values from the drive number
contained in the zero page lOCB field ICDNOZ.
5) Allocate a sector buffer to the FCB if one is not already
allocated.
Chapter Six
FMS
EXIT
There are two types of FMS exits: the normal exit and the error exits.
Both of these exit types end up calling the RETURN routine.
RETURN
Address -$12D3
Entry Registers — A = Return Code.
X = Don't Care.
Y = Don't Care.
Exit Registers — A = Possible 'Get Byte' data byte.
X = lOCB number times 16.
Y = Return Code.
Functions:
1 ) The X register is loaded with the current lOCB number times
16 from CURFCB.
2) The return code is placed in the ICXZ^B status field (ICSTA).
3) The stack register is restored to point to the stack displacement
at FMS entry from the value saved in ENTSTK.
4) The possible "Get Data" data byte is loaded into the A
register.
5) The Y register is loaded with the return code.
23
ClflAPTER SrX
6) The caller (CIO) is returned to via the RTS instruction.
eKEATAnd FGREAT
GP.EAT and FGREAT are the exit points used by FMS when the
operation has terminated normally. FGREAT is located at $12EA and
is used to free the sector buffer that has been allocated to the FCB.
The FRESBUF routine is used to free the buffer. FGREAT exits
directly to GREAT ($12F0). The GREAT exit point loads the normal
return code ($01) into the A register and goes to RETURN.
Error Exits
The ERREOF exit is called when an end of file condition is found.
ERREOF loads the end-of-file condition code ($88) in the A register
and goes to RETURN.
The ERRIO exit is called if an error occurs during an I/O operation
(Figure 1, control flow 3). The error code from the DCB (control
path K) is loaded into the A register as the FMS return code and
control is passed to RETURN.
All other errors exits are at the ERxxx labels starting at $12B5.
Th(; error code is developed by means of a series of 6502 INC
instructions which increment the ERRNO (which was initialized to
$9F at FMS entry). The final instruction at the end of the INC chain
loaiis the final ERRNO value into the A register and control is passed
directly to RETURN.
24
Chapter Seven
DEVICE
DEPENDENT
COMMANDS
A C'evice Dependent Command is any command which is not Open,
Close, Get Byte, Put Byte, or Status. When the command value in
the lOCB is greater than 15 ($0F), CIO will call the Device Handler
Device Dependent Command routine. The Device Handler must
det€;rmine if the command is a valid command for that device. The
Device Dependent Commands that for FMS are:
Rename
Delete
Lock
Unlock
Point
Note
Format
The FMS Device Dependent Command routine starts at
DFMDDC.
DFMDDC
Address - $BA7
Entry Registers - A = Don't Care.
X = lOCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = lOCB and FCB number times 16.
Y = Unknown.
Function:
1) Call SETUP
2) If the command is Format (254) , then go to the Format routine,
XFORMAT at $D18.
3) If the command is not Format, then check that the command
25
CHAPTER SEVEN
value is $20 through $26. If the command value is not in this
range then exit via the ERDVEXH (Command Error) routine.
4) If the command is valid, go to the command via the DCDCVT
vector table.
XFORMAT
The XFORMAT routine executes the FORMAT Device Dependent
Command.
Address -$D18
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1 ) Issue the format I/O command to the drive. This will cause
the drive to perform the physical formating of the disk. If the
command returns with good status and there were no bad sectors
reported, then continue with the logical format operations. In
the event of physical format errors, exit via the ERDBAD error
exit.
2) Clear the drive buffer to zero.
3) Set the sector count values into the DVDMSN (VTOC
displacement one) and the DVDNSA (VTOC displacement
three) fields.
4) Set all 90 sector bit map bits to one (available).
5) Deallocate the first four sectors for the boot sectors.
6) Deallocate the middle nine sectors for the VTOC and the
Directory.
7) Write the VTOC to the Disk.
8) Clear the eight directory sectors to zero.
9) Exit via the FGREAT exit.
XDELETE
The XDELETE routine executes the DELETE Device Dependent
Command.
Address — $C3 2
Entry Registers - A = Don't Care.
26
CHAPTER SEVEN
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Parameters - A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1) The filename is decoded via the FNDCODE routine.
2) The first filename is searched for via the SFDIR routine.
3) The file, if found, is deleted via the XDELO routine.
4) If the file just deleted was DOS. SYS then the boot record is
re-written via the DELEXDS routine.
5) The directory is searched for the next matching entry. If an
entry is found then the process repeats at step three. If no further
matching directory entries are found, then exit via FGREAT.
XOELO
Tbe XDELO routine is used to delete the file whose directory entry is
indicated by the CDIRD (current Directory Displacement) byte
($1305).
Address - $C53
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1 ) The OPVTOC routine is called to insure that the disk is not
write protected.
2) The TSTLCXZIK routine is called to insure that the file is not
locked.
3) The file deleted bit is set in the directory entry flag and the
directory sector is written back to the disk.
4) The VTOC sector bit map bits for the sectors in the file are
set to one to make them eligible for reuse. This process is achieved
by reading each sector in the file sector chain and calling the
FRESECT routine to change the VTOC bit map.
5) The VTOC Write Required Bit is set so that the VTOC will
be written back to the disk.
27
CI-IAPTER SEVEN
XRENAME
The XRENAME routine executes the RENAME Device Dependent
Command.
Address - $BD9
Entry Registers - A = Don't Care.
X = ICXDB and FCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1) The filename is decoded via the FNDCODE routine.
2) The directory is searched for the first entry to be renamed. If
no entry is found then the ERFNF (File not found) exit is taken.
3) The TSTLOCK routine is called to insure that the file is not
locked.
4) If TSTDOS determines that the old filename is DOS. SYS
then the boot record is rewritten via the DELDOS routine.
5) If new filename is EXDS.SYS, then the boot record is rewritten
via the SETDOS routine.
6) The filename in the directory is changed to the new filename.
7) The directory sector is rewritten.
8) The directory is searched for the next filename match. If a
match is found, then the process repeats at step three. If no
further match is found then, exit via FGREAT.
XLOCKAndXUNLOCK
The XLOCK routine executes the LOCK Device Dependent
Command. The XUNLOCK routine executes the UNLOCK Device
Dependent Command.
Address — $C7C
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = Unknown.
Y = Unknown.
28
CHAPTER SEVEN
Functions:
1) The XLOCK entry sets the LOCK bit value, DFDLOC ($20),
into TEMP4. The XUNLOCK entry sets a zero value into TEMP4.
Both routines then go to XLCOM.
2) The filename is decoded via the FNIDCODE routine.
3) The directory is searched for the first file entry match. If no
match is found, the ERFNF (file not found) exit is taken.
4) The files directory flag is modified to either LCX3KED or
UNLCXZlKED by means of the value previously set into TEMP4.
5) The Directory sector is written back to the disk.
6) The CSFDIR routine is called to find the next filename match.
If a match is found, then the process repeats at step four. If no
match is found, then exit via FGREAT.
XPOINT
Th(; XPOINT routine executes the POINT Device Dependent
Command.
Address - $CBA
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1 ) If the FCBFLG indicates that the file can acquire sectors
(Opened for Output or Append), then exit via the ERRPOT
(point error) exit.
2) If the current sector is not the same as the sector POINTed to
by the lOCB AUX3 and AUX4 fields, then write the current
sector back to the disk (if it has been changed).
3) Read the POINTed to sector into the sector buffer.
4) Set the FCB next byte pointer, FCBDLN, to the value
indicated by the user Point data in the lOCB AUX5 field.
5) Exit to FGREAT.
XhlOTE
The XNOTE routine executes the NOTE Device Dependent
Command.
29
CHAPTER SEVEN
Address - $D03
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1 ) The current sector number and data displacement into the
sector is moved to the appropriate ICXHB fields, ICAUX3,
ICAUX4, 1CAUX5.
2) Exit via GREAT.
30
Chapter Eight
FMS
OPEN
ROUTINES
The FMS Open routine, DFMOPN, is called directly by CIO via the
FMS Device Vector Table, DFMSDH at $7CB.
DFMOPN
The DFMOPN routine is the FMS file open routine.
Address - $8AB
Entry Registers — A = Don't Care.
X = lOCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1 ) Initialize for this operation by calling SETUP.
2) Decode the filename via FNDCODE.
3) Examine the open code in ICAUXl for the open-for-directory-
read command. If this is a directory read command, go to
LISTDIR.
4) If not a directory read, then search the directory for the first
match on the file name and save the resulting search condition
on the stack.
5) Determine the exact type of Open operation to be performed
by examining the lOCB ACUXl field. If INPUT, go to DFOIN.
If Output, go to DFOUT. If Update, go to DFOUPD. If Append,
go to DFOAPN. If none of the above, exit via the ERDVDC
(device command error) exit.
31
CHAPTER EIGHT
DPOIN
DFOIN ($8D8) is entered when opening a file for Input. The routine
pops the stack to determine if the directory search for the file name
was successful. If the file name was found in the directory, then go to
DFOUI. If the search was not successful, then exit to ERFNF (file not
found).
DI^OUPD
DFOUPD ($8DD) is entered when opening a file for Update (Input
and Output). The routine pops the stack to determine if the file name
was found in the directory. If the file was not found, then exit to
ERFNF (file not found). If the file was found, insure that the file is
noi: Locked by calling TSTLOCK. If the file is unlocked, then continue
at 13FOUI.
DFOUI
DFOUI ($8E3) is entered to finish opening a file for Input or Update.
The read setup routine, DFRDSU, is called. FMS then exits via the
GREAT exit.
DFDRDSU
DFDRDSU ($9AE) is entered to set up a data file for reading. It
beg:ins by calling SETFCB to set some standard file information into
the FCB. It continues by setting up the FCB with various other
parameters to read the first data sector in the file. This sector is read
via the RDNSO routine. When the sector has been read into the
sector buffer, the code returns to the caller.
DFOAPN
DFOAPN ($BEC) is entered to open a file for Append.
1 ) Pop the stack to determine if the file has been found in the
directory. If the file was not found exit via ERFNF.
2) if the file was created by DOS 1 , then exit via ERAPO.
3) Insure the file is not locked by calling TSTLOCK.
4) Insure the diskette is not write protected by calling
OPVTOC.
5) Allocate a new sector for the start of the Append chain by
calling GETSECTOR.
6) Save the sector number of the sector obtained in FCBSSN so
that it will be available when the file is closed.
32
CHAPTER EIGHT
7) Continue opening the file as if it were being opened for
Output at DHFOX2.
DI=OOUT
The DFOOUT ($911) routine is entered when opening a file for
Output.
1 ) Pop the stack to determine if the file was found in the
directory.
2) If the file was found, then delete it via the XDELO ($C53)
routine.
3) If the file was not found, then make a new entry in the directory
via the code at DFOXl ($9 ID).
4) Allocate a data sector for the file via the GETSECTOR
routine.
5) Put the necessary information about the file into the directory
and write the directory sector back to the disk.
6) Continue at DHFOX2.
Dlf1FOX2
DHFOX2 ($97C) is entered to finish the Open process for files that
are being opened for Output or Append.
1) Finish initializing the FCB via SETFCB.
2) If the TSTEKDS routine determines that the file name being
opened is DOS. SYS, then write out DOS via the WRTDOS
routine.
3) Exit via GREAT.
SIITFCB
The SETFCB ($995) routine is used in the various Open file routines
to place certain common data into the FCB.
33
Chapter Nine
FMS
CLOSE
ROUTINES
The; FMS close routine is called directly by CIO via the FMS Device
Vector Table, DFMSDH at $7CB.
DFMCLS
Address -$B15
Entry Registers - A = Don't Care.
X = lOCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1) Initialize via call to SETUP.
2) If the file was not opened for some form of output (Output,
Update or Append) then clear the FCB open flag, FCBOTC and
exit via FGREAT.
3) If the FCBFLG indicates that the file has not acquired sectors,
then continue at CLUPDT to close the Update file.
4) Write the last data sector via WRTLSEC.
5) Read the file's directory sector into the directory buffer via the
RRDIR routine.
6) Get the sector count from the directory.
7) If the file was opened for Output (i.e. it is not open for
Append), then continue at CLOUT.
8) Read all the data sector of the file until the end-of-file sector
is found.
9) Place the sector address of the start of the Append chain into
the link sector field of the (old) end-of-file sector.
10) Continue at CLOUT.
34
CHAPTER NINE
CLOUT
The CLOUT ($B50) routine is entered to finish closing a file that had
been opened for Output or Append.
1 ) The sector count field of the directory is updated.
2) The open for output flag is turned off.
3) The file in use flag is set.
4) The directory sector is written back to the disk by the DRTDIR
routine.
5) The VTOC sector is written back to the disk by the
WRTVTOC routine.
6) The FCB open code flag, FCBOTC, is cleared to zero.
7) Exit via FGREAT.
CLUPDT
The CLUPDT ($B75) is called to finish the closing of a file that had
been opened for Update.
1 ) If the current sector in the sector buffer has been modified
then write it back to the disk via the WRCSIO routine.
2) Clear the FCB open flag, FCBOTC, to zero.
3) Exit via FGREAT.
35
Chapter Ten
GET BYTE
ROUTINE
The FMS GET BYTE routine, DFMGET, is called directly by CIO
via tlie FMS Device Vector Table, DFMSDH at $7CB. The GET
BYTE routine's function is to get and return the next sequential data
byte to CIO.
DFMGET
Address - $ABF
Entry Registers - A = Don't Care.
Y = lOCB number times 16.
X = Don't Care.
Exit Registers - A = Unknown.
Y = Unknown.
X = Unknown.
Functions:
1 ) Initialize via the SETUP routine.
2) If the FCB is opened for Directory read, then go to
GDCHAR.
3) If the current sector is empty, attempt burst I/O (see Burst I/O
section), then continue with number four.
4) Read the next sector via the RDNXTS routine. If the read
sector operation did not return an end-of-file condition, then
continue at step three, else exit via ERREOF (end-of-file error).
5) Get the data byte from the sector and place it in SVDBYT for
the exit routines.
6) If the next byte in the file is the end-of-file byte, exit via
RETURN with the impending end-of-file condition code ($03),
else exit via GREAT.
36
Chapter Eleven
PUT BYTE
ROUTINE
The FMS PUT BYTE routine, DFMPUT, is called directly by CIO
vin the FMS Device Vector Table, DFMSDH at $7CB. The PUT
B^fTE routine's function is to place the single data byte transmitted by
CIO into the data sector.
DIFMPUT
Address -$99C
Entry Registers - A = The "put data" data byte.
X = The lOCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1 ) The data byte in the A register is saved in SVDBYT.
2) SETUP is called to initialize for this operation.
3) If the caller was not CIO, then prevent a burst I/O operation
from occurring.
4) If the file was not opened for output, then exit via ERDVDC
(device command error).
5) If the current data sector is full, write the sector via WRTNXS,
then attempt burst I/O (see BURST I/O section). If a burst I/O
operation did take place, then get the next byte after the area
just written by burst I/O and place it into the SVDBYT cell.
6) Increment the sector data byte count.
7) Move the data byte from SVDBYT to the next available data
byte in the sector.
8) Set the sector modified flag in the FCB.
9) Exit via GREAT.
37
Chapter Twelve
BURST I/O
The CIO is designed to fill or empty a large user buffer with data bytes
sent to or received from a device handler, a byte at a time. To fill a
thousand-byte buffer, CIO would have to call FMS one thousand
times in rapid succession. While the process is simple and easy to
implement by both CIO and the Device Handlers, it can be very
slow. This is particularly true in the case of FMS which has a great
deal of overhead code to go through each time it is called. FMS
circLimvents most of the CIO/FMS calls for large data transfers via the
BURST I/O routines.
Burst I/O operates by reading or writing data sectors directly into
the user buffer (Figure 1, data path I). There are a number of tests
that must be passed before a burst I/O operation can take place. If any
of the tests fail, then the CIO/FMS data transfer reverts to the normal
mode of operation.
When the PUT BYTE routine is called, it will call the WTBUR
($A1F) routine when it is ready to start filling a new data sector.
WTBUR will not allow a burst I/O operation to happen if the file has
been opened for Update. If the file has not been opened for Update,
then WTBUR goes to the common read/write burst I/O test routine,
TBL'RST at $A28. If the file has been opened for Update, then exit
Burst I/O indicating that a Burst I/O did not happen. When WTBUR
calls TBURST, it has the A register set to non-zero to indicate that it
is write.
When the GET BYTE routine is called, it will call the RTBUR
($A26) routine when it is ready to read a new data sector. RTBUR
indicates that it is read by setting the A register to zero and then
enters TBURST.
TBURST
1 ) Save the A register in BURTYP. This value will indicate if
the burst operation is a read or a write.
2) If the I/O command in the lOCB is for text I/O (a transfer
that is to end when the Atari end-of-line ($9B) character is
transferred), then TBURST will exit indicating (carry set) that a
burst I/O operation did not occur.
38
CHAPTER TWELVE
3) If the user buffer length in the lOCB is not at least a full
sector in size, then exit without doing a burst I/O.
4) If all the above tests pass, then perform a burst I/O operation.
The first step in the burst I/O operation is to change the zero
page sector buffer pointer, ZXBA ($47) from the FMS sector
buffer address to the user buffer address.
5) If the operation is read, then read the next sector via RDNXTS.
If the read sector operation produced an end-of-file, then go to
BUREOF, else go to BBINC.
6) If the operation is write, then the area in the user buffer,
where the three bytes of data sector control information is to be
placed, will be saved. The data will be written via the WRTNXS
routine. The saved user data will then be copied back into the
user buffer. The code then continues at BBINC.
BBINC
The BBINC routine is entered after a single burst I/O sector has been
read or written. BBINC updates data counters in the FCB and in the
\OCB and tests for the end of the Burst I/O.
1 ) The zero page sector buffer pointer is incremented by the
length of data in a sector (125 or 253).
2) The user buffer length is decremented by the length of data in
a sector.
3) The TBLEN routine is called to determine if there is enough
room left in the user buffer to read or write another full sector
( 128 or 256 bytes). If another sector can be read or written, then
the process repeats at NXTBUR ($A3E).
4) If there is not enough room in the user buffer to perform
another full sector read or write, then BUREOF is entered.
BUREOF
1) The final address in the zero page sector pointer, ZSBA ($47),
is moved to the lOCB buffer address field.
2) The value in the zero page sector buffer pointer is restored by
the SSBA routine.
3) The caller is returned to with the carry cleared to indicate
that a burst I/O operation has happened.
59
Chapter Thirteen
READING
THE DIRECTORY
AS A FILE
A formatted subset of the data in the Directory can be read as if the
Direi:tory were a disk file. This is accomphshed by using the open
directory code ($02) in the lOCB ICAUXl byte. When FMS
recognizes this code in the Open routine (at $8B1), it will go directly
to the LISTDIR routine. The LISTDIR routine prepares the FCB for
reading the directory as a file. The GET BYTE routine will recognize
the read directory condition from information stored in the FCBOTC
field (see $AC2) and go directly to the directory read character I/O
routine GDCHAR.
LISTDIR
Address - $DAD
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = Unknown.
Y = Unknown.
Functions:
1) The TEMP4 byte is used to count the characters that have
been transmitted by GDBYTE from the formatted line buffer.
LISTDIR sets this value to zero to indicate the start of a new
formatted line.
2) The SFDIR routine is called to start a wild card search for the
file name in the directory.
3) If a match is found then FDENT is called to format the entry
and prepare for the GDBYTE calls. Exit via GREAT.
4) If a match is not found, then LDCNT is called to prepare to
send the xxx FREE SECTORS line.
40
CHAPTER THIRTEEN
GDCHAR
G1X:HAR ($DB9) is entered from GET BYTE to get a single data
byte from a formatted directory line.
1) The TEMP4 flag is tested. If the value is negative, then all
formatted information has been transmitted. Exit is via the
ERREOF (end-of-file error) exit.
2) The value in TEMP4 is used as an index into the formatted
line buffer to get the next character. The character is placed into
SVDBYT for loading into the A register by the RETURN
routine.
3) The character retrieved from the buffer is examined for the
EOL ($9B) character.
4) If the character is not an EOL, then exit is via GREAT.
5) If the character was an EOL, then the line length is examined
to see if the line was a directory entry line (i.e. , if the length was
17) or the final xxx FREE SECTORS.
6) If the line was the final line, then TEMP4 is set to a negative
value ($80) to indicate that all formatted lines have been sent.
Exit is via GREAT.
7) If the line was not the final line, then CSFDIR is called to
find the next matching file name.
8) If a file name match is found, then FDENT is called to format
the found entry into the formatted line buffer. Exit is via
GREAT.
9) If a file name match is not found, then go to LEXI^NT to
format the final line.
LDCNT
LIX^NT ($DE9) formats the final line of a directory read.
1) Read the VTOC.
2) Get the free sector count from the VTOC and convert it to
ATASCII via the CVDX routine.
3) Move the FREE SECTORS message to the formatted line buffer.
4) EXIT is via FGREAT.
FDENT
The FDENT ($E21) routine formats the current directory entry into
the formatted line buffer for subsequent reading by GDBYTE.
1) The directory flag is checked for the file locked condition. If
41
the file is locked, then the "*" is placed in the formatted line.
2) The file name is moved from the directory entry to the
formatted line.
3) The file sector count is converted to AT ASCII and placed in
the formatted line.
4) The EOL character is placed in the formatted line.
5) Exit is via the RTS instruction.
Chapter Fourteen
SECTOR
I/O
ROUTINES
The FMS performs sector I/O by calling the SIO routine in the OS
ROM (Figure 1, control path 3). All sector I/O calls in the FMS occur
frorri the BSIO routine. There are several other routines that are
designed to set up information for BSIO. These routines deal with
reading and writing sectors of a particular type such as data sectors,
directory sectors, and the VTOC sector.
BSIO
Address — $76C
Entry Registers - A = Sector number most significant byte.
Y = Sector number least significant byte.
X = If 1, then 128 byte I/O (810 drive).
If 2, then 256 byte I/O (815 drive).
Exit Registers - A = Status byte from DCB.
Y = Unknown.
X = lOCB and FCB number times 16.
42
CHAPTER FOURTEEN
Functions:
1) The sector number is stored in the DCB from the A,Y register
pair. The EXHB is the interface control block for SIO calls.
2) If the carry is clear, then the DCB is set up for read data. If
the carry is set, then the DCB is set up for write data.
3) The serial bus ID for the disk, and the disk timeout values are
placed into the DCB.
4) The error retry counter, RETRY, is set for four retries.
5) The I/O data length is set to 128 or 256 depending upon the
data in the X register.
6) The serial I/O routine ($E459) is called to execute the I/O.
7) If the I/O operation was good, then the X register is loaded
with the lOCB (and FOB) number times 16 from the CRFCB
cell and the status byte from the DCB is loaded into the A register.
Return is via the RTS instruction.
8) If the I/O operation was bad, then the retry counter is
decremented. If the retry value is positive, then the I/O is retried.
If the value is negative, then the routine is exited in the manner
described in step seven.
Ds;io
The DSIO routine is called to perform data sector I/O operations.
Address -$11F7
Entry Registers - A = Sector number most significant byte.
Y = Sector number least significant byte.
X = lOCB and FCB number times 16.
Exit Registers — A= I/O condition code.
Y = Unknown.
X = lOCB and FCB number times 16.
Functions:
1 ) The sector buffer address is obtained from the zero page sector
buffer pointer ZSBA ($47) and placed in the DCB buffer address
field, DCBBUF.
2) The drive type byte is loaded into the X register from DRVTYP.
If the drive is an 810, then the value will be one. If the drive is
an 815, then the value will be two.
3) BSIO is called.
4) The DSIO caller is returned to via the RTS instruction.
43
CHAPTER FOURTEEN
RDDIRAndWRTDIR
The RDDIR and the WRTDIR routines are used to perform Directory
sector I/O operations. The RDDIR entry ($106E) sets the carry to
indicate read. The WRTDIR entry ($1071) clears the carry to indicate
write. Both of the routines continue at DIRIO.
DIRIO
1) Save the read/write flag (carry sense) on the stack.
2) Set the address of the directory buffer into the DCB buffer
field, DCBBUF.
3) The CDIRS cell contains the number of the directory sector
to be read or written. This value ranges from zero to seven. The
DIRIO routine creates the actual sector number to read or write
by adding $169 to the CDIRS value. The resulting sector number
is placed in the A, Y register combination.
4) Continue at DSYSIO.
RDWOC And WRTVTOC
The RDVTOC and WRTVTOC routine are called to initiate I/O to
and from the VTOC sector. The RDVTOC routine ($108B) first
checks the write required byte in the VTOC sector buffer. If the value
of this byte is not zero, then the VTOC is already in the buffer (and
has been changed). If the VTOC is already in the buffer, then the
read does not have to be done; therefore, the RDVTOC routine will
return to the caller. If the write-required byte is zero, then RDVTOC
will clear the carry to indicate that the operation is read. The
WRTVTOC routine ($1095) sets the write required byte to zero, then
sets i:he carry to indicate a write operation. Both Rt)VTOC and
WRTVTOC continue at VTIO.
VTIO
1 ) The read/write flag is pushed onto the stack.
2) The VTOC sector buffer address is moved from the zero page
drive buffer address pointer ZDRVA ($45) to the DCB buffer
pointer, DCBBUF.
3) The A,Y register combination is loaded with the VTOC
sector number ($168).
4) Continue at DSYSIO.
DSYSIO
1 ) The read/write sense is popped from the stack.
44
CHAPTER FOURTEEN
2) The drive type value is loaded into the X register from
DRVTYP.
3) BSIO is called.
4) If the I/O operation was good, then return to the caller via the
RTS instruction.
5) If the I/O operation was bad, the exit via the ERRSYS exit
(fatal system I/O error).
OI>VTOC
The OPVTOC routine ($10BF) is used by various FMS routines to
insure that the diskette is not write protected before executing functions
that will write to the disk. This routine will read the VTOC via
RDVTOC and then attempt to write the VTOC via WRTVTOC. If
the diskette is write protected, the WRTVTOC will cause an I/O
error exit (error number 144). If the diskette is not write protected,
then the routine will return to the caller. When OPVTOC does
return to the caller, the current disk VTOC is in the drive buffer.
45
Chapter Fifteen
FILE NAME
DECODE
ROUTINE
The FNEXI^ODE routine is used to transform the user suppUed file
name into a form that is usable in FMS for wild card searching of the
direc:tory. The primary and extension parts of the user file name are
padded with blanks and question marks as required. The following
examples show the types of transform performed by FNEXDODE:
User File Name
Transformed File Name
D:*.*
77777777777
Dl:GLOP.*
GLOP ???
Dl:GLOP.BAS
GLOP BAS
D2:*.ASM
????????ASM
D:GL?P.S*
GL?P S??
D1:G*
G7777777
FNC»CODE
Address - $E9E
Entry Registers -
-A
= Don't Care.
X
= lOCB and FCB number times 16.
Y
= Don't Care.
Exit Registers —
A
= Unknown.
X
= lOCB and FCB number times 16.
Y
= Unknown.
Functions:
1 ) The user file name buffer is searched for the colon (:) delimiter.
If the delimiter is not found within 256 characters then exit to
ERRFN routine (file name error).
2) The FMS file name buffer, FNAME, is cleared to blanks.
3) The EXTSW byte is set to zero. When EXTSW is zero, the
primary file name field is being processed. When EXTSW is
46
CHAPTER FIFTEEN
minus, then the extension file name field is being processed.
4) The next character in the user file name buffer is examined.
5) If the character is an asterisk ('), then the field is padded with
question mark characters to the end of the field.
6) If the character is a period and the extension field is being
processed, then exit via the RTS instruction.
7) If the character is a period and the primary field is being
processed, then switch to the extension field processing.
8) If the character is a question mark, then put it into the FN AME
via FDSCHAR.
9) If the character is alphanumeric (A through Z, or through
9), then put it into FN AME via FDSCHAR.
10) If the character is none of the above, then assume that end
of the filename has been found and exit via the RTS instruction.
11) If a character was stored, then continue at step four.
FDSCHAR
1 ) If the character counter register, X, indicates that the primary
field is full, then exit without storing the character.
2) If the character counter register, X, indicates that the extension
field name is full, then exit without storing the character.
3) Store the character into FN AME indexed by the X register.
4) Increment the X register.
5) Return to caller via the RTS instruction.
47
Chapter Sixteen
DIRECTORY
SEARCHING
The Directory search routine searches the directory entries for a file
name that matches the name in FNAME. The routine has two entry
points: SFDIR which is used to begin the search at the start of the
directory, and CSFDIR, which is used to continue searching the
directory at the entry just past the previously found matching entry.
The routines have five memory cells that they use for controlling
the search operation: DHOLES, DHOLED, CDIRS, CDIRD and
SFNUM. The CDIRS cell contains the current relative directory
sector number (zero through seven). The CDIRD cell contains the
displ acement into the directory sector of the current entry. DHOLES
gives the relative directory sector number (zero through seven) of the
first hole or available entry in the directory. TTie DHOLED cell gives
the displacement to the first available entry that is the hole. The
SFNUM cell is used to contain the current file number of the entry
being examined. The value in SFNUM will be from zero through 63.
If the value of DHOLES is $FF at the end of the search, then the
directory is full.
The directory search routine will exit with the carry clear if a
match was found. It will exit with the carry set if no matching entry
was found.
SFDIR
The SFDIR routine ($F21) is called to start searching the directory at
the start of the directory.
1) Initialize DHOLES, CDIRS, SFNUM to $FF.
2) Initialize CDIRD to $70.
3) Continue at CSFDIR.
CSFDIR
The CSFDIR routine ($F3 1 ) is called to continue searching the
directory.
1) Increment the file number, SFNUM.
48
CHAPTER SIXTEEN
2) Increment CDIRD by the size of a directory entry (16).
3) If the CDIRD is now greater than, or equal to, 128 ($80) then
increment CDIRS by one. If the value of CDIRD is now eight,
then exit with the carry set to indicate that a match was not
found. If CDIRD is less than eight, then read the next directory
sector via RDDIR. Set CDIRD to zero.
4) If the directory entry flag field is zero then the end of the used
portion of the directory has been reached. If a hole has not been
found, then mark this entry as a hole. Exit with the carry set to
indicate that the file was not found.
5) If the directory entry flag field indicates that the file is open
for output, then skip this entry.
6) If the directory entry flag field indicates that the file has been
deleted, and a hole has not been found, then mark this entry as a
hole and continue searching the directory.
7) If the file is in use, then check the file name in the directory
entry for a match with the name in FNAME. Wild card characters
in FNAME (question marks) are assumed to match the
corresponding characters in the directory entry file name.
8) If the names match, then exit with the carry clear to indicate
that a match was found.
9) If a match was not found, then continue to search the
directory.
49
Chapter Seventeen
WRITE
NEXT
SECTOR
The write next sector routine, WRTNXS, is used to write a data
sector to disk.
Address - $F94
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers — A = Unknown.
X = lOCB and FCB number times 16.
Y = Unknown.
Functions:
1 ) If the file has been opened for update, and the sector has not
been modified, then do not write the sector. Read the next data
sector and then return to caller.
2) If the file has been opened for update, and the sector has been
modified, then write the current sector. Read the next data
sector into the sector buffer and return to the caller.
3) If the file is not opened for update, then allocate a new sector
to the file by calling GETSECTOR.
4) Move the sector byte count from the FCB FCBDLN field to
the data sector byte count field.
5) Move the address of the newly acquired sector from the FCB
FCBLSN field into the link field of the current data sector.
6) Write the current sector to the disk via WRCSIO.
7) If the I/O was bad, mark the FCB by placing a zero value into
FCBOTC as closed and exit via RETURN with the I/O error
number as the return code.
8) If the I/O was good, then increment the FCB sector counter
field, FCBCNT.
50
9) Call MVLSN to move the sector number of the link sector
number field of the FCB, FCBLSN, to the current sector number
field of the FCB,FCBCSN.
10) Set the current data length field of the FCB, FCBDLN, to
zero.
11) Set the maximum data length field of the FCB, FCBMLN,
to 125 (if 810 drive) or 253 (if 815 drive).
12) Return to user via the RTS instruction.
Chapter Ei
READ
NEXT
SECTOR
Th«; read next sector routine, RDNXTS, reads the next sector in the
file sector chain into the sector buffer. If there are no more sectors in
the chain, then the routine returns with the carry set to indicate end-
of-file. If the routine returns with the carry clear, then the next sector
has been read.
RDNXrS
Address -$100F
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = lOCB and FCB number times 16.
Y = Unknown.
Functions:
1) If the file has been opened for Update, then WRTNXS is
51
CIHAPTER EIGHTEEN
called to write the current sector if it has been modified.
2) If the FCB link sector number field, FBCLSN, is zero then
there are no further sectors to read. Return to the caller with the
carry set to indicate that the end-of-file has been reached.
3) Call MVLSN to move the FCB link sector number field,
FCBLSN, the FCB current sector number field, FCBCSN.
4) Call RWCSIO with the carry set to read the next sector.
5) If the I/O operation was bad, exit via the ERRIO exit (I/O
error) .
6) Insure that the file number in the sector just read agrees with
the file number in the FCB. If the file numbers are not the same,
exit via the ERFNMM exit (file number mismatch). Note: if the
routine was called by delete, return to delete indicating end-of-
file.
7) Move the link sector number from the data sector to the FCB
link sector field in the FCB, FCBLSN.
8) Move the sector data length information from the data sector
to the FCB maximum data length field, FCBMLN.
9) Reset the FCB data length field, FDBDLN, to zero.
10) Return to the caller with the carry clear to indicate that a
sector has been read.
52
Chapter Nineteen
GET AND
FREE
SECTOR
ROUTINES
TbiC get sector routine, GETSECTOR, is called when a new sector is
needed. The routine searches the bit map in the VTOC for a free
sector. The sector found is deallocated from the bit map and the
sector number is returned to the caller. The free sector routine,
FR.ESECT, is given a sector number to be freed. FRESECT locates
the required bit map bit in the VTOC and turns it on (sets it to one).
The sector is now eligible for reuse.
GETSECTOR
Address -$1106
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = ICXIlB and FCB number times 16.
Y = Unknown.
Functions:
1 ) The Y register is used as an index into the bit map bytes.
2) The bit bytes are examined sequentially from the first bit map
byte to the last bit map byte until a non-zero byte is found. The
displacement to this byte is saved in TEMPI.
3) If no bits are found in the bit map, then the ERRNSA exit
(no sectors available) is taken.
4) The number-of-sectors-available-field, in the VTOC, is
decremented by one.
5) The VTOC write required byte in the VTOC is set to a non-
53
CHAPTER NINETEEN
zero value to indicate that the VTOC has been changed and
must be written back to the disk.
6) The non-zero bit map byte that was found in the bit map
search is retrieved. The bits in this byte are shifted left until a bit
moves into the carry flag. The carry is then set clear and the bits
shifted back to their original position. The byte with the newly
allocated sector bit turned off is placed back into the bit map.
7) The number of bits shifted and the index to the bit map byte
are used to develop the sector number represented by the Ijit.
8) The sector number is stored in the FCB link sector field,
FCBLSN.
9) The user then returned to via the RTS instruction.
FRIESECT
Address -$10C5
Entry Registers - A = Don't Care.
X = lOCB and FCB number times 16.
Y = Don't Care.
Exit Registers - A = Unknown.
X = lOCB and FCB number times 16.
Y = Unknown.
Furictions:
1 ) The sector to be freed is in the FCB current sector field,
FCBCSN. If the sector number is zero, then FRESECT exits
back to the user via the RTS instruction.
2) The sector number is divided by eight to determine the bit
map byte which represents the sector. The remainder from this
division represents the bit within the byte.
3) The byte is retrieved from the bit map, the bit is turned on,
and the byte placed back into the bit map.
4) The number of available sectors field in the VTOC is
incremented by one.
5) The VTOC write required byte is set to non-zero to indicate
that the VTOC has been changed and needs to be written back
to the disk.
6) The caller is returned to via the RTS instruction.
54
Chapter Twenty
THE
BOOT PROCESS
When the Atari computer is turned on, the routines in the OS ROM
will (under certain conditions) read the first sector from the disk in
drive one into memory. It will then examine certain specific locations
in this record to decide how to boot the disk. In the following
discussion, refer to Figure 20-1. The OS ROM code will load BRCNT
consecutive sectors (starting with sector one) onto memory, starting
at the address contained in BLDADR. When the OS ROM code has
finished this task, it will make a JSR call to the code that is seven
bytes into the start of the boot area. In the case of FMS, this is the
JMP XBCONT instmction at $706. The XBCONT code will continue
the boot load process.
The XBCONT code examines the DFSFLG to see if a DOS. SYS
file exists. If the file exists, then the sector number of the first sector
in DOS. SYS will be in DFLINK. The routine will then read all the
sectors in the chain starting at DFLINK into the memory area pointed
to by DFLADR. When the entire DOS. SYS file is read into memory,
X13CONT returns to the OS ROM code.
The OS ROM code will eventually vector through the BINTADR
so that the FMS can initialize itself. In the DOS 2. OS system,
BINTADR points into the DUP.SYS code. DUP.SYS then receives
control from the OS ROM rather than the FMS. One of the tasks that
DUP.SYS performs during its initialization is to call the FMS
initialization routine.
XBCONT
The XBCONT routine ($714) is entered by the OS ROM code during
tbie boot process to allow the boot process to continue in the manner
best suited for the code being booted.
Functions:
1) If the DFSFLG indicates that a DOS. SYS file does not exist,
then the OS ROM is returned to with the carry set to indicate
that the boot has failed.
55
CHAPTER TWENTY
2) The address contained in DFLADR is moved to the zero page
address pointer, ZBUFP, and to the DCB buffer pointer field,
DCBBUF.
3) The sector number contained in DFLINK is loaded into the
A, Y register pair, the carry is cleared to indicate read, and BSIO
is called to read a DOS. SYS sector.
4) The next sector link is obtained from the link field of the data
sector just read.
5) If the sector link value is zero, then the DOS. SYS end-of-file
has been reached. The OS ROM will be returned to with the
carry clear to indicate that the boot read was good.
6) If the sector link value is not zero, then the zero page buffer
pointer and the EXHB buffer pointer are incremented by the
amount of data in the sector (125 for 810 drives, 253 for 815
drives).
7) The process continues by reading the next sector into
memory.
Sector 1
Sector 2
$700
$780
Sector 3 $800
$700
BFLAG
Flag( = 0)
$701
BRCNT
Number of Consecutive Sectors to Read
$702
BLDADR
Address to Load Boot Sectors at
$704
BIWTARR
Initialization Address
$706
JMPXBCONT
Boot Continue Vector
$709
SABYTE
Number of Sector Buffers to Allocate
$70A
DRVBYT
Drive Bits
$70B
Unused
$70C
SASA
Buffer Start Address
$70E
DFSFLG
DOS Flag
$70F
DFLINK
Sector Pointerto DOS.SYS File
$711
BLDISP
Displacement in Sector to Sector Link
$712
DFLADR
Address of Start of DOS.SYS File
Figure 20-1
Boot Records
56
Chapter Twenty-One
MAINTAINING
THE
BOOT RECORD
The boot record (sector 1) contains information about the DOS. SYS
file. When LX)S.SYS is opened for output, FMS will write all of FMS
out to the disk as part of the open process. It will also modify sector
zero to indicate that a CXDS.SYS file exists and to indicate where on
the disk it is. If DOS. SYS is ever Deleted or Renamed (to something
not DOS. SYS), then the boot record must be modified to indicate
that a DOS. SYS file does not exist. If a file is ever renamed to
EX)S.SYS, then the boot record is modified to point to the new
DOS. SYS file.
WRTDOS
The WRTDOS routine ($120A) is used to write a new DOS. SYS file
to disk and to update the boot record to indicate that a EXDS.SYS file
exists.
Functions:
1 ) The sector number which is contained in the FCB sector
number link field, FCBLSN, is used as the first sector of the
DOS. SYS file. This sector number is placed in the boot record
area in page seven along with the other necessary information.
2) Sectors one, two, and three are written from the memory area
from $700 through $87F.
3) The FMS is written to the EXDS.SYS via the WDO routine.
4) Exit is via GREAT.
WDO
Tl-ie WDO routine ($1267) is used to write the FMS to the DOS.SYS
file.
Functions:
1 ) The address contained in DFLADR is moved to the zero page
57
CMAPTER TWENTY-ONE
buffer pointer, ZBUFP.
2) The FMS is copied from its area in memory to the file sector
buffer in 125 byte chunks.
3) The buffers are written to disk by the WRTNXS routine.
4) The process continues until the entire FMS area has been
written.
5) The caller is returned to via the RTS instruction.
DliLDOS
Tbe DELIX)S routine ($1219) is used to modify the boot record to
indicate that DOS. SYS does not exist.
Functions:
1) The DFSFLG is set to zero to indicate that DOS. SYS does not
exist.
2) The area from $700 to $87F is written to sectors one, two,
and three.
3) The caller is returned to via the RTS instruction.
58
ATARI
DOS
2.0S
Copyright © 1982 Optimized Systems Software, Inc.
Thii listing is protected against unauthorized reproduction by the Copyright Law of the United
Stales. Any reproduction utiUzed for profit or other commercial advantage is precluded without
the specific prior written authorization of Optimized Systems Software, Inc., the owner of the
cop /right. Any such reproduction does not constitute fair use and may subject the individual to
both civil and criminal penalties. Federal Law provides for a maximum fine of $10,000 or
imprisonment for not more than one year, or both, for infringement of this copyright.
Contact the President, Optimized Systems Software, Inc., 10379 Lansdale Avenue, Cupertino,
California, 95014, prior to reproducing or utilizing any portion of this listing. Any attempt to
change the form of publication of this listing, that is, rendering it into machine-readable form or
othjrwise, is a precluded reproduction if done for profit or other financial advantage.
59
ATARI DOS 2.0S
FMS - 128/256 BYTE SECTOR {2.0S)
Copyright and Author Notice
0030
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 ;
System Equates
.PAGE " Copyright and Author Notice —
COPYRIGHT (C) 1978,1979,1980,1982
OPTIMIZED SYSTEMS SOFTWARE,
CUPERTINO, CA.
THIS PROGRAM MAY NOT BE REPRODUCED,
STORED IN A RETRIEVAL SYSTEM, OR
TRANSMITTED IN WHOLE OR IN PART,
IN ANY FORM, OR BY ANY MEANS, BE IT
ELECTRONIC , MECHANICAL, PHOTOCOPYING,
RECORDING, OR OTHERWISE WITHOUT THE
PRIOR WRITTEN PERMISSION OF
OPTIMIZED SYSTEMS SOFTWARE, INC.
10379 LANSDALE AVENUE
CUPERTINO, CALIFORNIA 95014 (U.S.
A.)
PHONE: (408) 446-3099
***********************************
PROGRAMMER PAUL LAUGHTON
UPDATED: 19-AUG-80
.***********************************
0000
0700
0043
03 40
0003
03 00
E453
00 9B
03 lA
0020
02E7
1540
0102
00 DF
0246
000F
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
.PAGE " System Equates"
***********************************
FMSORG =
FMSZPG =
lOCBORG =
LMASK =
DCBORG =
DHADR =
EOL
DEVTAB =
ZICB
LMADR =
DUPINIT =
1045 STAR
1046 OSBTM =
1047 DSKTIM
1048 TIMOUT =
$700
?43
$340
03
$300
$E453
$9B
$31A
$20
$2E7
$1540
$102
$DF
$246
15
;LINK MASK
rlNIT ADDR FOR DUP
; STACK LOC FOR PUT BYTE
;HI BYTE OF ADDR LESS THAN OS
SPACE
rADDR OF OS WORST CASE DISK
TIME OUT
;TIME OUT VALUEE OF 15 SECS.
0000
1049
0000
1050
1051
1052
1053
1054
1055
1056
.PAGE " lOCB"
*= lOCBORG
lOCB - 10 CONTROL BLOCK
THERE ARE 8 1/0 CONTROL BLOCKS
1 lOCB IS REQUIRED FOR EACH
CURRENTLY OPEN DEVICE OR FILE
60
ATARI DOS 2.0S
034»
0341
034:2
0343
0344
0343
034'5
03413
0349
034A
034:3
03 40
0340
034E
034F
0010
0350
0001
0002
0003
0004
0005
0006
000 7
0008
00e9
00eA
00eB
00ec
00eD
00i'E
00CIE
00C1F
0001
00(12
1057 lOCB
1058 ICHID
*—
*+l ;
DEVICE NUMBER
1059 ICDNO
*—
*+l
DEVICE HANDLER
1060 ICCOM
*—
*+l
I/O COMMAND
1061 ICSTA
*a
*+l ;
I/O STATUS
1062 ICBAL
*s
*+l
1063 ICBAH
* —
*+l ;
BUFFER ADR (H,L)
1064 ICPUT
*—
*+2
PUT CHAR DH ADDR
1065 ICBLL
*—
*+l
1066 ICBLH
*ss
*+l
BUFFER LEN (H,L)
1067 ICAUXl
*s
*+l ;
AUX 1
1068 ICAUX2
* —
*+l
AUX 2
1069 ICAUX3
*—
*+l
AUX 3
1070 ICAUX4
*—
*+l
AUX 4
1071 ICAUX5
*—
*+l
AUX 5
1072 ICAUX6
*—
*+l
AUX 6
1073 ICLEN
=
*-IOCB
1074 ;
1075
*s
*+ICLEN*7
SPACE FOR 7 MORE lOCB'S
1076 ;
1077 ; ICCOM VALUE EQUATES
1078 ;
1079 ICOIN
=
$01
•OPEN INPUT
1080 ICOOUT
=
$02
fOPEN OUTPUT
1081 ICIO
=
$03
;OPEN UN/OUT
1082 ICGBR
=
$04
;GET BINARY RECORD
1083 ICGTR
=
$05
; GET TEXT RECORD
1084 ICGBC
s
$06
;GET BINARY CHAR
1085 ICGTC
=
$07
;GET TEXT CHAR
1086 ICPBR
=
$08
;GET BINARY RECORD
1087 ICPTR
=
$09
;PUT TEXT RECORD
1088 ICPBC
=
$0A
;PUT BINARY CHAR
1089 ICPTC
=
$0B
;PUT TEXT CHAR
1090 ICCLOSE =
$0C
;CLOSE FILE
1091 ICSTAT
=
$0D
;GET STATUS
1092 ICDDC
=
$0E
; DEVICE DEPENDENT
1093 ICMAX
=
$0E
;MAX VALUE
1094 ICFREE
=
$0F
;IOCB FREE INDICATOR
1095 ;
1096 ; ICSTA VALUE EQUATES
1097 ;
1098 ICSOK
=
$01
; STATUS GOOD, NO ERRORS
1099 ICSTR
=
$02
;TRUNCAIATED RECORD
lOCB
00193
1100
ICSEOF
=
$03
;END OJ
FILE
0080
1101
ICSBRK
=
$80
; BREAK
KEY ABORT
00131
1102
ICSDNR
=
$81
; DEVICE NOT READY
0032
1103
ICSNED
=
$82
;NON EXISTENT DEVICE
0033
1104
ICSDER
=
$83
;DATA ERROR
0034
1105
ICSIVC
=
$84
; INVALID COMMAND
0035
1106
ICSNOP
=
$85
; DEVICE/FILE NOT OPEN
0036
1107
ICSIVN
=
$86
; INVALID lOCB #
00 87
1108
1109
ICSWPC
=
$87
;WRITE
PROTECT
1110
r ZERO
PAGE
lOCB LABELS
1111
;
0021
1112
ICDNOZ
=
ICDNO-
-lOCB+ZICB
0028
1113
ICBLLZ
=
ICBLL-
■lOCB+ZICB
BUF LEN
0029
1114
ICBLHZ
=
ICBLH-
-lOCB+ZICB
0024
1115
ICBALZ
=
ICBAL-
-lOCB+ZICB
BUF ADDR
0025
1116
ICBAHZ
=
ICBAH-
-lOCB+ZICB
0022
1117
ICCOMZ
=
ICCOM-
-lOCB+ZICB
0026
1118
ICPUTZ
=
ICPUT
-lOCB+ZICB
•PUT RTN ADDR
61
ATARI DOS 2.0S
DCB
17A0
17A0
0300
0301
030 2
030 3
0304
0306
0303
030A
005:2
0050
0053
002 L
000:.
008].
008:!
0083
0084
008 V
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
.PAGE " DCB"
*= DCBORG
DCB - DATA CONTROL BLOCK
THE DCB IS AN lOCB LIKE CONTROL
BLOCK USED TO INTERFACE THE DISK
FILE MANAGEMENT SYSTEM TO THE
DISK HANDLER
DCB
DCBSBI *=
DCBDRV *=
DCBCMD *=
DCBSTA *=
DCBBUF *=
DCBTO *=
DCBCNT *=
DCBSEC *=
*+l
*+l
*+l
*+l
*+2
*+2
»+2
*+2
; SERIAL BUS ID
;DISK DRIVE #
; COMMAND
,-I/0 STATUS
;l/0 BUFFER ADDR (H,L)
;TIME OUT CNT
;l/0 BYTE COUNT
;l/0 SECTOR NUMBER
DCBCMD VALUE EQUATES
DCBCRS =
DCBCWS =
DCBCST =
DCBCFD =
'R
'P
'S
• 1
;Read sector ($52)
;Put sector ($50)
;Status request ($53)
r FORMAT DISKETTE ($21)
*** SPECIAL NOTE:
DCBCWS may be changed to 'W ($57)
if desired to have disk perform
a verifying read after each write.
Disk write ( 'W) operations will take
longer, but will be more reliable.
DCBSTA VALUE EQUATES
DCBSOK = $01 rSTATUS NORMAL
DCBDNR = $81 ; DEVICE NOT READY
DCBCNR = $82 ; CONTROLLER NOT READY
DCBDER = $83 ;DATA ERROR
DCBIVC = $84 ; INVALID COMMAND
DCBWPR = $87 ; WRITE PROTECT
030c:
030c:
004;:
004!;
0047
0049
004;.
004;.
ZERO PAGE
1161
1162
1163
1164
1165
1166
1167
1168
1169
15
20
.PAGE " ZERO PAGE"
*= FMSZPG
ZBUFP *= *+2
ZDRVA *= *+2
ZSBA *= *+2
ERRNO *= *+l
.•BUFFER PTR
;ZERO PG DRIVE PTR
;ZERO PG SECTOR BUF PTR
TERROR NUMBER
.INCLUDE #E:
.INCLUDE *D:ATFMS1.SRC
BOOT RECORD
004;>
004;,
2000
2001
2002
2003
2004
.PAGE "BOOT RECORD"
*= FMSORG
THE FOLLOWING BYTES ARE STORED
ON DISK SECTOR THEY COMPRISE
62
ATARI DOS 2.0S
07e0 00
eiei 03
07e2
0704
0706
0007
4015
4C1407
0709
070A
070B
070C
03
01
00
0115
07I3E 00
070F
0710
0711
0712
00
00
7D
CB07
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
THE BOOT LOAD RECORD
BFLG
BRCNT
.BYTE
.BYTE
BLDADR .WORD FMSORG
BINTADR .WORD DUPINIT
BCONT JMP XBCONT
;BOOT FLAG UNUSED=0
;N0 CONSECTIVE BOOT
READ
;B0OT LOAD ADDR
;INIT ADDR
;BOOT READ CONT PT
RECORDS TO
THE FOLLOWING BYTES ARE SET BY
■ THE CONSOLE PROCESSOR. THEY ARE
: ACTED UPON DURING FMS INIT ONLY,
r THEY ARE PART OF THE BOOT RECORD
; THUS DEFINING THE DEFAULT
[INITIALIZATION FARMS
SABYTE
DRVBYT
SAFBFW
SASA
.BYTE 3
.BYTE 01
.BYTE
.WORD ENDFMS
MAX # CONCURRENT OPEN FILES
DRIVE BITS
STORAGE ALLOCATION DIR SW
STORAGE ALLOCATION START ADDR
THE FOLLOWING CODE READS THE FMS
AND CONSOLE PROCESSOR (DOS) FROM
THE DOS. SYS FILE
DFSFLG .BYTE
; 00 NO DOS FILE
; 01 128 BYTE SECTOR
: 02 256 BYTE SECTOR
DFLINK .BYTE 0,0
2036 BLDISP
2037 DFLADR
2038 ;
2039 XBCONT
00714 AC0E07 2040
.BYTE
.WORD
125
DFMSDH
;DOS FLAG
DISK
DISK
;DOS FILE START SECTOR NUMBER
;DISPL TO SECTOR LINK
,-ADDR START OF DOS . SYS FILE
0717 F036
0719
071C
071E
0721
AD1207
8543
8D0403
AD1307
0724 8544
0726 8D0503
2041
2042
2043
2044
2045
2046
2047
2048
2049
LDY
BEQ
LDA
STA
STA
LDA
STA
STA
DFSFLG
BFAIL
DFLADR
ZBUFP
DCBBUF
DFLADR+1
ZBUFP+1
DCBBUF+1
;GET DOS
;BR IF NO
FLAG
DOS . SYS
MOVE LOAD START ADDR
TO ZERO PAGE PTR
AND TO DCB
BOOT RECORD
2050 ;
0729
AD1007
2051
LDA
DFLINK+1
;GET 1ST SECTOR #
072C
AC0F07
2052
LDY
DFLINK
072P
18
2053 XBCl
CLC
0730
AE0E07
2054
LDX
DFSFLG
;LOAD DISK TYPE COl
0733
206C07
2055
JSR
BSIO
;G0 READ BOOT SECT(
0736
3017
2056
2057 ;
BMI
BFAIL
07 38
AC1107
2058
LDY
BLDISP
; POINT TO LINK
07 3B
B143
2059
LDA
(ZBUFP)
Y
;GET LINK HI
07 3D
2903
2060
AND
#LMASK
;MASK TO LINK BITS
0'i3F
48
2061
PHA
0740
C8
2062
INY
0741
1143
2063
ORA
(ZBUFP)
Y
0T43
F00E
2064
BEQ
BGOOD
0745
B143
2065
LDA
(ZBUFP)
Y
;GET LINK LOW
0747
A8
2066
TAY
63
ATARI DOS 2.0S
074H 205707
07411 68
074C 4C2F07
0741' A9C0
0751 D001
0753 68
0754 0A
0755 A8
07 56 60
0757
075EI
075;.
075D
0760
076::
076A
0766
076!i
07611
18
A543
6D1107
8D0403
8543
A544
6900
8D0503
8544
60
SECTOR I/O
076C
076C
076C 8D0B03
076F 8C0A03
0772 A952
0774 A040
0776 9004
0778 A950
077A A080
077C 8D0203
077F 8C0303
0782 A931
0784 A00F
0786 8D0003
0789 8C0603
078C A903
078E 8DFP12
0791 A900
0793 A080
0795 CA
0796 F004
0798 A901
079A A000
079C 8D0903
2067
2068 ;
2069
2070
2071 ;
2072 BFAIL
2073
2074 ;
2075 BGOOD
2076 ;
2077 XBRTN
2078
2079
2080 ;
2081 INCBA
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091 ;
JSR INCBA
PLA
JMP
LDA
BNE
PLA
ASL
TAY
RTS
CLC
LDA
ADC
STA
STA
LDA
ADC
STA
STA
RTS
XBCl
#5C0
XBRTN
ZBUFP
BLDISP
DCBBUF
ZBUFP
ZBUFP+1
#0
DCBBUF+1
ZBUFP+1
;G0 INCREMENT BUF ADR
; RESTORE LINK HI
;G0 READ NEXT SECTOR
;SET FOR CARRY SET
;ANY P,Y = $80
;SET FOR CARRY CLEAR
rlNC BUFFER PTR
;BY DATA LINK (125)
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
.PAGE "SECTOR I/O"
; BSIO - DO SECTOR I/O
BSIO = *
STA
STY
DCBSEC+1
DCBSEC
BSIOR LDA #DCBCRS
LDY #$40
BCC DSIOl
LDA #DCBCWS
LDY #$80
DSIOl
DSI02
STA DCBCMD
STY DCBSTA
LDA #$31
LDY #TIMOUT
STA DCBSBI
STY DCBTO
; SET SECTOR HI
; SECTOR LO
r ASSUME READ SECTOR
,-AND GET DATA
;BR IF READ
;ELSE LOAD WRITE SECTOR
;AND PUT DATA
;SET COMMAND
rAND SIO CMD
;DISK SERIAL BUS ID
.•TIMEOUT DEFAULT LOADED
LDA
STA
#3
RETRY
LDA
LDY
DEX
BEQ DSI03
#0
#$80
LDA
LDY
#1
#0
;SET ID
;SET TIME OUT
;SET RETRY COUNT
;ASSUME 128 BYTE
.•SECTOR DISK
;S0 BR
;ELSE IS 256
DSI03 STA DCBCNT+1 ; SET I/O BYTE CNT
64
ATARI DOS 2.0S
079F 8C0803
2131
2132 ;
2133 DSI04
STY
DCBCNT
07A2 2059E4
2134
JSR
$E459
07A5 101D
2135
2136 ;
BPL
DSI05
07A7 CEFF12
2137
DEC
RETRY
07AA 3018
2138
2139 ;
BMI
DSI05
7AC A240
2140
LDX
#$40
7AE A952
2141
LDA
#DCBCRS
07B0 CD0203
2142
CMP
DCBCMD
SIJCTOR I/O
07B3 F009
2143
BEQ
STRTYP
07B5 A921
2144
LDA
#DCBCFD
07B7 CD0203
2145
CMP
DCBCMD
07BA F002
2146
BEQ
STRTYP
07BC A280
2147
LDX
#$80
07£E 8E0303
2148 STRTYP
2149 ;
STX
DCBSTA
07C1 4GA207
2150
2151 ;
JMP
DSI04
07C4 AE0113
2152 DSI05
LDX
CURFCB
07C7 AD0303
2153
LDA
DCBSTA
07CA 60
2154
2155 ;
RTS
;CALL SERIAL I/O
;IF GOOD I/O THEN RTS
;TST IF ANOTHER RETRY AVAIL
;N0 THEN RTS WITH ERROR
DO RETRY-RESET TYPE ACTION
ASSUME READ-CK IF IS
IF COMMAND GET SECTOR
;YES THEN STORE GETSECTOR IN
;TEST IF FORMAT CMD
;IT ALSO RECIEVES DATA
rYES THEN SET AS GET DATA
;ELSE STORE PUTSECTOR
; RETRY THE l/O
; RELOAD CURRENT FCB
;AND I/O STATUS SET FLAGS
FILE MANGER ENTRY POINT
7CB
07CB AA08
07CD 140B
07CF BE0A
07D1 CB09
07D3 000B
07D5 A60B
07D7
7E0
Gi7E0 AD0C07
CI7E3 8543
CI7E5 AD0D07
CI7E8 8544
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
.PAGE "FILE MANGER ENTRY POINT"
; DFMSDH - DISK FILE MANAGEMENT DISK
; HANDLER ENTRY POINT
DFMSDH
.WORD DFMOPN-1 ;OPEN FILE
.WORD DFMCLS-1 ;CLOSE FILE
.WORD DFMGET-1 ;GET FILE
.WORD DFMPUT-1 ; PUT BYTE
.WORD DFMSTA-1 ; STATUS
.WORD DFMDDC-1 ;DEVICE DEPENDENT CMD
INITIALIZATION CODE
GIVE ROOM FOR BOOT EXPANSION 1 1 1
*= $7E0
DINIT = *
; SET UP DRIVE INFO
; DRVTBL - 8 BYTES-ONE FOR EACH POSSIBLE DRIVE
; = NO DRIVE
r 1 = 128 BYTE SECTOR DRIVE
r 2 = 256 BYTE SECTOR DRIVE
; DBUFA(L,H) 8 TWO BYTE ENTRYS THE
: DRIVE (VTOC) BUFFER ADR FOR A DRIVE
LDA SASA
STA ZBUFP
LDA SASA+1
STA ZBUFP+1
.-MOVE START OF ALLOC
;AREA TO ZBUFP
65
ATARI DOS 2.0S
07E*
07Er'
AD0A07
8D0C13
07Fe A207
07F2
07F5
07FE
07F*
07FC
07FF
0802
0805
8E0D13
0E0C13
B00D
A900
9D1113
9D2913
9D3113
F036
2192
2193
2194 ;
2195
2196 ;
2197 DIA
2198
2199
2200 ;
2201
2202
2203
2204
2205
2206 ;
LDA
STA
STX
ASL
BCS
LDA
STA
STA
STA
BEQ
DRVBYT
TEMPI
LDX #7
TEMP2
TEMPI
DIHAVE
*0
DRVTBL.X
DBUFAL.X
DBUFAH.X
DIDDEC
;TEMP 1 IS DRIVE
; EXCESS BITS FROM BOOT
;TEMP 2 IS
;DR # MINUS 1
; SHIFT DR BIT TO CARRY
;BR IF DR EXISTS
DRVTBL.X ;SET NO DRIVE
;G0 DEC DRIVE #
FILE MANGER ENTRY POINT
0807 A005
0809 A900
080B 9143
080D E8
080E 8B0103
0811 A953
0813 8D0203
0816 2053E4
0819 A002
081B ADEA02
081E 2920
0820 D001
0822 88
0823
0824
082 7
082A
082C
082F
0831
0834
98
AE0D13
9D1113
A543
9D2913
A544
9D3113
207008
0837 88
0838 F003
083A 207008
083D CA
083E 10B2
0840 AC0907
0843 A200
0845 A900
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
DIHAVE
LDY #DVDWRQ ; SET WRITE READ OFF
LDA #0
STA (ZBUFP),Y ;IN THE DRIVE BUFFER
;PUT DR # IN DCB
;GET DRIVE STATUS
DI256
INX
STX
DCBDRV
LDA
#DCBCST
STA
DCBCMD
JSR
DHADR
LDY
#2
LDA
$2EA
AND
#$20
BNE
DI256
PEY
TYA
LDX
TEMP2
STA
DRVTBL.X
LDA
ZBUFP
STA
DBUFAL.X
LDA
ZBUFP+1
STA
DBUFAH.X
JSR
DINCBP
DEY
BEQ
DIDDEC
JSR DINCBP
DIDDEC PEX
BPL DIA
.•ASSUME 256 BYTE DRIVE
;GET STATUS BYTE
,-BR IF 256
;SET DR TYPE INTO
;TBL AT DRIVE DISPL
;MOVE CURRENT ALLOC
;ADDR TO DBUFA
;AND INC ALLOC
rBY 128 BYTES
;VIA DINCBP
;IF DR WAS A
;128 BYTES THEN DONE
;ELSE INC PTR BY 128
;DEC DRIVE
;BR IF MORE TO TEST
SET UP SECTOR ALLOCATION TABLE
THE SECTOR ALLOCATION TABLE (SECTBL)
WAS 16 ONE BYTE ENTRIES ONE FOR
EACH POSSIBLE 128 BYTE BUFFER SABYTE
IN THE BOOT RECORD DETERMINES THE
NUMBER OF ENTRYS TO ALLOCATE
NON-ALLOCATED BYTE ARE MINUS
SABUF(L.H) CONTAINS THE ADDR OF THE SECTOR BUFFER
;GET AND SAVE COUNT
LDY SABYTE
LDX #0
DINXTS LDA #0
; ASSUME ALLOCATE
66
ATARI DOS 2.0S
01347 88 2256
0848 1001 2257
084A 98 2258
DEY ;DEC COUNT OF ALLOCATED
BPL DISETS ;IF PLUS STILL ALLOCATE
TYA ;ELSE DE ALLOCATE
FILE MANGER ENTRY POINT
2259
;
034B
9D1913
2260
DISETS
STA
SECTBL.X
,-SET ALLOCATE BYTE
0B4E
98
2261
TYA
;IF NO ALLOCATED
0B4F
300D
2262
2263
}
BMI
DISNI
;THEN DON'T ALLOC A'
0851
A543
2264
LDA
ZBUFP
rMOVE BUFFER ADDR
0B53
9D3913
2265
STA
SABUFL, X
;T0 SECTOR BUF PTR
0856
A544
2266
LDA
ZBUFP+1
0858
9D4913
2267
STA
SABUFH.X
085B
207008
2268
2269
,
JSR
DINCBP
!lNC SECTOR ADDR
085E
E8
2270
DISNI
INX
;INC BUF #
085F
E010
2271
CPX
#16
;IF NOT ALL 16
0861
D0E2
2272
2273
BNE
DINXTS
;D0 AGAIN
2274
,- SET :
LOW MEM
2275
0863
A543
2276
LDA
ZBUFP
;MOVE FINAL ADDR
0865
8DE702
2277
STA
LMADR
.•TO LOW MEM PTR
0868
A544
2278
LDA
ZBUFP+1
086A
8DE802
2279
2280
;
STA
LMADR+1
086D
4C7E08
2281
2282
!
JMP
CLRFCB
;CONT INIT
2283
; DINCBP -
INC ZBUFP
BY 128
2284
;
e870
18
2285
DINCBP
CLC
e871
A543
2286
LDA
ZBUFP
e873
6980
2287
ADC
#128
e875
8543
2288
STA
ZBUFP
8877
A544
2289
LDA
ZBUFP+1
8879
6900
2290
ADC
#0
e87B
8544
2291
STA
ZBUFP+1
e87D
60
2292
2293
,
RTS
2294
; CLEAR FCBS TO ZERO
2295
•
ei87E
2296
CLRFCB
=
*
ei87E
A07F
2297
LDY
#?7F
;128 OF FCB
CI880
A900
2298
LDA
#0
(1882
998113
2299
CFCBX
STA
FCB.Y
;T0 BE CLEARED
0885
88
2300
DEY
0886
D0FA
2301
2302
;
BNE
CFCBX
FILE
MANGER
ENTRY
POINT
0B88
2303
.PAGE
2304
;
0888
A000
2305
LDY
#0
088A
B91A03
2306
ADIl
LDA
DEVTAB.Y
;FIND AH
088D
F00C
2307
BEQ
ADI2
; UNUSED
088F
C944
2308
CMP
#'D
;0R DISK
0891
F008
2309
BEQ
ADI2
; EMPTY
0893
C8
2310
INY
0894
C8
2311
INY
0895
C8
2312
INY
0896
C01E
2313
CPY
#30
0898
D0F0
2314
BNE
ADIl
089A
00
2315
2316
;
BRK
;ELSE BREAK
67
ATARI DOS 2.0S
089B A944
2317 ADI2 LDA #'D
089D ')91A03 2318
08A0 A9CB 2319
08A2 991B03 2320
08A5 A907 2321
08A7 991C03 2322
2323
08AA i50 2324
STA
LDA
STA
LDA
STA
RTS
;SET DISK
DEVTAB , Y
#DFMSDHS,2 55
DEVTAB+1,Y
#DFMSDH/2 56
DEVTAB+2 , y
rSET FMS ADDR
OPEN
08AB
2325
.PAGE "OPEN"
2326
;
2327
1 DFMOPN -
FILE OPEN
EXECUTION ENTRY PT
2328
;
2329
DFMOPN
08AB
206411
2330
JSR
SETUP
; DO FOB SET UP
08AE
209E0E
2331
JSR
FNDCODE
;G0 DECODE FILE NAME
08B1
BD4A03
2332
LDA
ICAUXl , X
; GET AUXl (OPEN TYPE CODES)
08B4
9D8213
2333
STA
FCBOTC.X
;PUT INTO FCB
08B7
2902
2334
AND
#OPDIR
; IS THIS LIST DIRECTORY
08B9
F003
2335
BEQ
OPNl
;BR IF NOT
08BB
4CAD0D
2336
2337
.
JMP
LISTDIR
;GOT0 DIR LIST CODE
08BE
20210F
2338
OPNl
JSR
SPDIR
;GO SEARCH FILE DIR
08C1
08
2339
2340
.
PHP
08C2
BD8213
2341
LDA
FCBOTC.X
;GET OPEN TYPE CODE
08C5
C904
2342
CMP
#OPIN
; INPUT
08C7
F00F
2343
BEQ
DFOIN
08C9
C908
2344
CMP
#OPOUT
r OUTPUT
08CB
F044
2345
BEQ
DFOOUT
08CD
C90C
2346
CMP
#OPIN+OPOUT ; UPDATE
08CF
F00C
2347
BEQ
DFOUPD
08D1
C909
2348
CMP
♦OPOUT+OPAPND ; APPEND
08D3
F017
2349
BEQ
DFOAPN
08D5
4CBF12
2350
2351
.
JMP
ERDVDC
TERROR
2352
; DFOIN - OPEN FOR INPUT
2353
;
08D8
2354
DFOIN
=
*
08D8
28
2355
PLP
;GET SEARCH FLAG
08D9
B00E
2356
BCS
OPNERl
; ERROR IP NOT FOUND
08DB
9006
2357
2358
,
BCC
DFOUI
2359
; DFOUPD -
OPEN FOR UPDATA
2360
;
08DD
2361
DFOUPD
=
*
08DD
28
2362
PLP
;GET SEARCH FLAG
08DE
B009
2363
BCS
OPNERl
rBR NOT FOUND
08E0
20AC0C
2364
2365
.
JSR
TSTLOCK
;TEST LOCK
08E3
2366
DFOUI
=
*
08E3
20AE09
2367
JSR
DFRDSU
;SET UP FOR READ
08Ee
4CF012
2368
2369
.
JMP
GREAT
rDONE
08E9
4CBB12
2370
OPNERl
JMP
ERFNF
;FILE NOT FOUND
OPEN
f
08EC
2371
.PAGE
2372
;
2373
; DFOAPN -
OPEN APPEND
2374
•
08EC
2375
DFOAPN =
*
08EC
: 28
2376
PLP
;GET READ STATUS
68
ATARI DOS 2.0S
0(iED
0(!EF
0HF2
0HF5
0HF7
0f)F9
0HFC
0f!FF
0902
0905
0908
090B
090E
B0FA
AC0513
B90114
2902
F015
20AC0C
20BF10
200611
9D8E13
BD8B13
9D8D13
4C7C09
4CB712
0911
0911 28
0912 B009
0914 20530C
0917 AC0513
091A 4C4809
09 ID
091D AD0213
0920 3070
0922 8D0613
0925
0928
092B
09 2 E
0931
0934
0937
093A
093C
093E
206E10
AD0313
8D0513
AD0413
8D0713
20BF10
AC0513
A20A
A920
990614
0'>41 C8
0942 CA
0943 10F9
0945 AE0113
0948
0948 200611
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
BCS
LDY
LDA
AND
BEQ
JSR
JSR
JSR
STA
LDA
STA
JMP
APOER JMP
OPNERl ;BR NOT FOUND
CDIRD ;IF OLD.
FILDIR+DFDFLl,y ;FILE TYPE
#DFDNLD
APOER ;
TSTLOCK 1
OPVTOC ;
GETSECTOR i
FCBSSN+1,X
FCBLSN.X ;
FCBSSN.X
DHF0X2 )
ERAPO
THEN
ERROR
TEST LOCKED
READ VTOC
GET A SECTOR
;MOVE START SECTOR
TO START SECTOR #
CONTINUE AS OPEN
DFOOUT - OPEN FOR OUTPUT
DFOOUT =
PLP
BCS
JSR
LDY
JMP
DFOXl
LDA
BMI
STA
JSR
LDA
STA
LDA
STA
JSR
LDY
LDX
LDA
2414 OPNIB STA
2415
2416
2417
2418
2419 ;
2420 OPNIA =
2421 JSR
INY
DEX
BPL
LDX
DFOXl
XDEL0
CDIRD
OPNIA
DHOLES
0PNER2
CDIRS
RDDIR
DHOLED
CDIRD
DHFNUM
SFNUM
OPVTOC
CDIRD
#10
#$20
FILDIR+DFDPFN.Y
OPNIB
CURFCB
rGET SEARCH FLAG
; DELETE THE FILE OR FILES
;WAS THERE A HOLE
;BR IF NO HOLE
rSAVE HOLE SECTOR AS CURRENT
DIR SEC
;G0 READ CURRENT DIR SECTOR
jMOVE HOLE DISPL TO
;CUR DIR DISPL
;MOVE HOLE FN
;T0 CURRENT
jBLANK FILL FILE ENTRY
FOR FILE NAME
GETSECTOR ;GET A SECTOR
OPEN
094B
AC0513
2422
LDY
034E
990514
2423
STA
0951
BD8B13
2424
LDA
0954
990414
2425
2426 ;
STA
0957
A943
2427
LDA
0959
990114
2428
STA
095C
A900
2429
LDA
095E
990314
2430
STA
0')61
990214
2431
2432 ;
STA
0964
A200
2433
LDX
0!)66
BD5913
2434 0PN2
LDA
0969
C93F
2435
CMP
096B
F003
2436
BEQ
CDIRD ;GET DIR DISPL
FILDIR+DFDSSN+1,Y ; PUT SECTOR INTO DIR
REC
FCBLSN.X
FILDIR+DFDSSN.Y
#DFDINU+DFDOUT+DFDNLD ;SET DIR ENTRY IN
USE
FILDIR+DFDFL1,Y
#0 ; SET NOT LOCKED
FILDIR+DFDCNT+1,Y ;SET COUNT =
FILDIR+DFDCNT,Y
#0
FNAME,X ;MOVE FILE NAME
*'? rIF WILD CARD
0PN2A ; CHANGE TO BLANK
69
ATARI DOS 2.0S
096D
990614
2437
STA
FILDIR+DFDPFN.Y ;T0 DIRECTORY
0970
2438
0PN2A
=
*
0970
C8
2439
INY
0971
E8
2440
INX
0972
E00B
2441
CPX
#11
0974
90F0
2442
2443
.
BCC
0PN2
0976
AE0113
2444
LDX
CURFCB
; RESTORE X REG
0979
207110
2445
JSR
WRTDIR
;G0 WRITE DIRECTORY
09 7C
2446
DHF0X2
=
*
097C
209509
2447
JSR
SETFCB
097F
20E20F
2448
JSR
WRTN6
;FIX UP AS IF WRITE
0982
A980
2449
0PN3
LDA
#FCBFAS
;SET NEW FILE
0984
9D8513
2450
STA
FCBFLG.X
0987
209B12
2451
JSR
TSTDOS
rIF NOT DOS
098A
D003
2452
BNE
DHF0X3
rBR
098C
4C0A12
2453
JMP
WRTDOS
;ELSE DO IT
098F
2454
DHF0X3
=
*
098F
4CF012
2455
2456
,
JMP
GREAT
0992
20BD12
2457
2458
2459
0PNER2
JSR
ERDFULL
.•DIRECTORY FULL
0995
2460
SETFCB
=
*
0995
A900
2461
LDA
#0
; CLEAR
0997
9D8513
2462
STA
FCBFLG.X
;FLAG
099A
AD0713
2463
OPNFl
LDA
SPNUM
;MOVE FILE NUM TO FCB
099D
0A
2464
ASL
A
099E
0A
2465
ASL
A
099F
9D8113
2466
STA
FCBFNO.X
09A2
A900
2467
LDA
*0
09A4
9D8713
2468
STA
FCBDLN.X
;DATA LENGTH
09A7
9D8F13
2469
STA
FCBCNT.X
;SET CNT =
09AA
9D9013
2470
STA
FCBCNT+1 ,
X
09AD
60
2471
RTS
09AE
209509
2472
DFRDSU
JSR
SETFCB
,-SET UP FCB
09B1
AC0513
2473
LDY
CDIRD
;MOVE START SECTOR TO LINK
OPEN
09B4
B90114
2474
LDA
DFDFLl+FILDIR.Y ;SET NEW
09B7
2902
2475
AND
♦DFDNLD
; SECTOR
09B9
9D8413
2476
STA
FCBSLT.X
;FLAG
09BC
B90414
2477
LDA
FILDIR+DFDSSN.Y
09BF
9D8B13
2478
STA
FCBLSN.X
09C2
B90514
2479
LDA
FILDIR+DFDSSN+1 . Y
09C5
9D8C13
2480
STA
FCBLSN+1 ,
X
09C8
201710
2481
JSR
RDNSO
;READ 1ST SECTOR
09CB
60
2482
RTS
09CC
25
.INCLUDE #E!
09CC
30
.INCLUDE #DiATFMS2.SRC
PUT EIYTE
09CC
3000
.PAGE "PUT BYTE"
3001
3002
r DFMPUT -
PUT A FILE
BYTE
3003
3004
DFMPUT
09CC
8D0813
3005
STA
SVDBYT
09CF
BD4103
3006
LDA
ICDNO.X
09D2
8521
3007
STA
ICDNO-IOCB+ZICB
09D4
206411
3008
JSR
SETUP
09D7
AC0013
3009
LDY
ENTSTK
;CHK TO SEE IF ENTRY WASN'T
FROM CIO
09DA
B90201
3010
LDA
STAK.Y
;IF HI BYTE RTS IS NOT IN OS
ADDR
70
ATARI DOS 2.0S
09I)D C9DF 3011
09I)F B004 3012
09I!1 A900 3013
09Ii3
091! 5
09i:8
09I!A
09I!C
091!F
091'0
09!''3
09F5
09)'8
091-'A
091?D
091?F
0A01
0AI93
8522
BD8213
2908
F02D
BC8713
98
DD8613
9011
20940F
B022
201F0A
A000
B005
B124
8D0813
0AI36 FE8713
0A09 AD0813
0Ai3C 9147
0AI2IE A940
0A10 1D8513
0A13 9D8513
0A16 4CF012
0A19 4CBF12
0AIC 4CF412
3014
3015 FRMCIO
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
302B
3029 ;
3030 PUTl
3031
3032
3033 ;
3034
3035
3036
3037 ;
3038
3039 ;
3040 PUTER
3041 PEOF
CMP
BCS
LDA
STA
LDA
AND
BEQ
LDY
TYA
CMP
BCC
JSR
BCS
JSR
LDY
BCS
LDA
STA
INC
LDA
STA
LDA
ORA
STA
#OSBTM ; SPACE THEN A NON-CIO ENTRY
FRMCIO ;BR IF FROM CIO
#0 ;ELSE PREVENT FROM DOING BURST
I/O
ICCOMZ
FCBOTC.X ;IF NOT OPEN
#OPOUT ; OUTPUT
PUTER ; ERROR
FCBDLN.X ;GET DATA LENGTH
FCBMLN.X ;IF SECTOR NOT FULL
PUTl ;THEN BR
WRTNXS ;ELSE WRITE FULL SECTOR
PEOF ;BR IF EOF
WTBUR rTEST BURST
#0
PUTl ;BR IF NOT BURST
(ICBALZ),Y ;PUT NEXT BYTE
SVDBYT rAFTER BURST AREA
FCBDLN.X ;INC DATA LEN
SVDBYT ;GET DATA BYTE
(ZSBA),Y ;AND PUT IN SECTOR BUFFER
#FCBFSM
FCBFLG.X
FCBFLG.X
! INDICATE SECTOR MODIFIED
JMP GREAT
JMP
JMP
ERDVDC
ERREOF
BURST I/O
0A1F
0S1F BD8513
0A22 1026
0A24 3002
0;>26 A900
0?.28 8D1013
0?.2B A522
0;i.2D 2902
0?.2F F019
0;31 20AE0A
0J.34 B014
0;l36 A524
0A38 8547
0;l3A A525
0;l3C 8548
0A3E AD1013
0A41 3009
0A43 200F10
0A46 9033
0A48 B053
0iUA 38
0iUB 60
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
.PAGE "BURST I/O"
; TEST BURST l/O AND DO IF POSSIBLE
WTBUR
LDA
BPL
BMI
FCBFLG.X
NOBURST
TBURST
RTBUR LDA #0
TBURST STA BURTYP
LDA ICCOMZ
AND #2
BEO NOBURST
JSR TBLEN
BCS NOBURST
LDA ICBALZ
STA ZSBA
LDA ICBAHZ
STA ZSBA+1
NXTBUR LDA BURTYP
BMI WRBUR
JSR RDNXTS
BCC BBINC
BCS BUREOF
NOBURST SEC
RTS
;IF NOT AQUIRING SECTORS
.-THEN UPDATE AND
;NO BURST
rSET READ TYPE
•SET BURST TYPE
;IF CMD
;IS TEXT MODE
;THEN NO BURST
;IF USER BUFFER LESS
;THEN SECTOR, NO BURST
;MOVE USER BUFFER
;ADDR TO SECTPOR
; BUFFER PTR
;GET I/O TYPE
;BR IF WRITE
J DO SECTOR READ
;BR IF EOF
;BR RD EOF
; INDICATE NO BURST
71
AT/iRI DOS 2.0S
3074 ;
0A4C
ADF812
3075 WRBUR
LDA
DRVMDL
;WRITE FULL SECTOR
0A4F
9D8713
3076
3077 ;
STA
FCBDLN,
X
;DATA COUNT
0A52
A8
3078
TAY
0A53
B147
3079
LDA
(ZSBA),
Y
rSAVE DATA TO BE
0A55
8D0913
3080
STA
SVDl
;T0 BE CLOBBERED
0A58
C8
3081
INY
0A59
B147
3082
LDA
(ZSBA),
Y
;BY WRTNXT
0A5B
8D0A13
3083
STA
SVD2
0A5E
C8
3084
INY
0A5F
B147
3085
LDA
(ZSBA),
Y
0A61
8D0B13
3086
3087 ;
STA
SVD3
0A64
20940F
3088
3089 ;
JSR
WRTNXS
;WRITE SECTOR
0A67
ACF812
3090
LDY
DRVMDL
; RESTORE CLOBBERED DAI
0AeA
AD0913
3091
LDA
SVDl
0A6D
9147
3092
STA
(ZSBA),
Y
BURST I/O
0A6F
C8
3093
INY
0A70
AD0A13
3094
LDA
SVD2
0A73
9147
3095
STA
(ZSBA)
Y
0A75
C8
3096
INY
0A76
AD0B13
3097
LDA
SVD3
0A79
9147
3098
3099 ;
3100 ;
STA
(ZSBA)
Y
0A7B
18
3101 BBINC
CLC
0A7C
A547
3102
LDA
ZSBA
;INC SECTOR
0A7E
7D8613
3103
ADC
FCBMLN
X
; BUFFER ADDR BY
0A81
8547
3104
STA
ZSBA
; ACTUAL DATA LEN
0A83
A548
3105
LDA
ZSBA+1
;GOT OT PUT
0A85
6900
3106
ADC
#0
0A87
8548
3107
3108 ;
STA
ZSBA+1
0A89
38
3109
SEC
0A8A
A528
3110
LDA
ICBLLZ
;DEC USER
0A8C
FD8613
3111
SBC
FCBMLN
X
; BUFFER LEN BY
0A8F
8528
3112
STA
ICBLLZ
; ACTUAL DATA LEN
0A91
A529
3113
LDA
ICBLHZ
;GOT OR PUT
0A93
E900
3114
SBC
#0
0A95
EA
3115
NOP
0A96
8529
3116
3117 ;
STA
ICBLHZ
0A98
20AE0A
3118
JSR
TBLEN
,-IF USER BUF LEN
0A9B
90A1
3119
3120 ;
BCC
NXTBUR
;NOW >= SECTOR, DO AG
0A9D
3121 BUREOF
=
*
;END OF BURSTING
0A9D
A547
3122
LDA
ZSBA
;MOVE FINAL ADDR BACK
0A9F
8524
3123
STA
ICBALZ
;T0 USER BUF PTR
0AA1
A548
3124
LDA
ZSBA+1
0AA3
8525
3125
3126 ;
STA
ICBAHZ
0AA5
BC8813
3127
LDY
FCBBUF
X
; RESTORE ZSBA
0AA8
88
3128
DEY
0AA9
20D011
3129
3130 ;
JSR
SSBA
0AAC
18
3131 BURST
CLC
0AAD
60
3132
3133 ;
RTS
3134 ,- TEST
USER
BUF LEN FOR BURST
3135 ;
0AAE
3136 TBLEN
= .
*
0AAE
ADFE12
3137
LDA
DRVTYP
;IF DRIVE NOT
72
ATARI DOS 2.0S
0AE1
C901
3138
CMP
#1
;128 BYTE SECTOR TYPE
0AEi3
D004
3139
3140 !
BNE
TBL256
;THEN DO 256 BYTE TEST
0AE;5
A528
3141
LDA
ICBLLZ
0AEi7
30F3
3142
3143
BMI
BURST
0AEI9
A529
3144 TBL256
LDA
ICBLHZ
;IF BUF LEN HI >= 256
BUBST
I/O
0AEB
D0EF
3145
BNE
BURST
;THEN CAN BURST
0AE;D
38
3146
SEC
0AE:E
60
3147
RTS
GET BYTE
0AI1F
3148
.PAGE "GET BYTE"
3149
3150
3151
DFMGET -
SET A FILE
BYTE
3152
0AI1F
3153 I
3FMGET
=
*
0ABF
206411
3154
JSR
SETUP
;G0 SET UP
0AC;2
BD8213
3155
LDA
FCBOTCX
rIF OPEN FOR
0A<;5
2902
3156
AND
#OPDIR
;DIR CNT
0A<;7
F003
3157
BEQ
GETl
0A(;9
4CB90D
3158
3159
JMP
GDCHAR
;THEN GO TO DIR RTN
0A(:c
BD8713
3160
3ET1
LDA
FCBDLN.X
;GET DATA LEN
0a(:f
DD8613
3161
CMP
FCBMLN.X
;TEST EMPTY SECTOR
0A132
900B
3162
BCC
GET 2
;BR IF NOT EMPTY
0A154
20260A
3163
JSR
RTBUR
;D0 BURST IF POSSIBLE
0A1)7
200F10
3164
JSR
RDNXTS
;GET NEXT SECTOR
0A1)A
90F0
3165
BCC
GETl
;BR IF NOT EOF
0A1X:
3166
3E0F
=;
*
0A1X;
4CF412
3167
3168
•
JMP
ERREOF
;ELSE EOF ERROR
0ADF
A8
3169
SET2
TAY
0AK0
B147
3170
LDA
(ZSBA),Y
;GET DATA BYTE
0a:52
8D0813
3171
STA
SVDBYT
rSAVE THE BYTE
0a:35
C8
3172
INY
0A:Ee
98
3173
TYA
0a:e7
9D8713
3174
STA
FCBDLN.X
;AND SET NEW VALUE
0AEA
3175
EFLOOK
=
*
0AEA
BC8B13
3176
LDY
FCBLSN.X
;D0 EOF LOOK AHEAD
0AED
D00F
3177
BNE
GET 3
;IF LSN NOT ZERO
0AEF
BC8C13
3178
LDY
FCBLSN+1 ,
X ;THEN
0AF2
D00A
3179
BNE
GET 3
;NOT EOF
0AF4
DD8613
3180
CMP
FCBMLN.X
;IF LSN=0 THEN CHECK F
0AF7
9005
3181
BCC
GET 3
;LAST BYTE
0AF9
A903
3182
LDA
#503
;IF LAST BYTE THEN RTS
00\FB 4CD312 3183
JMF
RETURN
3184
;
0AFE
4CF012
3185
GET3
JMP
GREAT
STATUS
0B01
3186
.PAGE "STATU
3187
;
3188
; DFMSTA -
GET A FI
3189
;
3190
DFMSTA
01301
206411
3191
JSR
SETUP
01304
209E0E
3192
JSR
FNDCODE
01307
20210F
3193
JSR
SFDIR
0130A
B006
3194
BCS
SFNF
FILE STATUS
; SETUP
; DECODE FILE NAME
; SEARCH FOR FILE
;BR NOT FOUND
73
ATARI DOS 2.0S
0B0C
20AC0C
3195
JSR
TSTLOCK
0B0F
4CF012
3196
3197
,
JMP
GREAT
0B12
4CBB12
3198
SFNF
JMP
ERFNF
;TEST LOCKED
;FILE EXISTS AND UNLOCKED
close;
0B15
0B15 206411
0B18 Bn8213
0B1B 2908
0B1D F04E
0B1F 3E8513
0B22 9051
0B24 20AB0F
0B27 20800B
0B2A BD9013
0B2D 48
0B2E BD8F13
0B31 48
0B32 BD8213
0B35 2901
0B37 F017
0B39 20AE09
0B3C 200F10
0B3F 90FB
0B41 BD8D13
0B44 9D8B13
0B47 BD8E13
0B4A 9D8C13
0B4D 20B30F
0B50 AC0513
0B53 18
0B54 68
0B55 790214
0B58 990214
0B5B 68
0B5C 790314
0B5F 990314
0B62 A942
0B64 990114
0B67 207110
0B6A 209510
0B6D A900
0B6F 9D8213
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
.PAGE "CLOSE"
DFMCLOSE
CLOSE A FILE
DFMCLS
JSR
LDA
AND
BEO
ROL
BCC
APPl
CLOUT
LDA
STA
LDA
STA
JSR
LDY
CLC
PLA
ADC
STA
PLA
ADC
STA
LDA
STA
JSR
JSR
CLDONE LDA
STA
SETUP
FCBOTCX
#OPOUT
CLDONE
FCBFLG.X
CLUPDT
;GET OPEN CODE
;IF NOT OUTPUT
;THEN DONE
;IF NOT ACQUIRING SECTORS
;THEN IS UPDATE
JSR WRTLSEC
RRDIR
FCBCNT+1 , X
;WRITE LAST SECTOR
GO GET DIRECTORY
;GET CNT OF SECTORS
JSR
LDA
PHA
LDA FCBCNT.X
PHA
LDA FCBOTC.X ;GET OPEN CODE
AND #OPAPND ;IF NOT APPEND
BEQ CLOUT ;BR
JSR DFRDSU
JSR RDNXTS
BCC APPl
;ELSE SET UP FOR READ
;READ TO EOF
FCBSSN.X rMOVE START SECTOR
FCBLSN.X TO EOF LINK SECTOR
FCBSSN+1,X
FCBLSN+1,X
WRTN2 ;THEN WRITE AS NOT EOF
CDIRD
;GET DIR DISPL
FILDIR+DFDCNT.Y
FILDIR+DFDCNT.Y
FILDIR+DFDCNT+l,y
FILDIR+DFDCNT+1,Y
#DFDINU+DFDNLD ;SET ENTRY TO IN USE
FILDIR+DFDFLl.Y
WRTDIR ;WRITE DIR
WRTVTOC .-WRITE VTOC
*0
FCBOTCX
; CLEAR OPEN CODE
CLOSE
0B72 4CEA12 3250
3251 ;
0B75 3252 CLUPDT
0B75 3E8513 3253
0B78 90F3 3254
JMP FGREAT
ROL
BCC
FCBFLG.X
CLDONE
;IF SECTOR NOT MODIFIED
;THEN DONE
74
ATARI DOS 2.0S
0B7A 20F80F 3255
0B7D 4C6D0B 3256
3257
JSR WRCSIO
JMP CLDONE
;ELSE WRITE IT
; THEN DONE
CLOSE
0Bf!0
3258
.PAGE
3259
;
3260
; RE-READ DIR RECORD
3261
;
0B(i0
3262
RRDIR
=
*
0B(!0
3D8113
3263
LDA
FCBFNO.X
0BH3
4A
3264
LSR
A
0BB4
4A
3265
LSR
A
0Bf)5
8D0713
3266
3267
3268
;
STA
SFNUM
0Bf)8
209B0B
3269
JSR
FNSHFT
03 »B
8D0613
3270
STA
CDIRS
0BBE
209B0B
3271
JSR
FNSHFT
0B<»1
209D0B
3272
JSR
FNSHFl
0B!>4
0A
3273
ASL
A
0B95
8D0513
3274
3275
;
STA
CDIRD
0B<)8
4C6E10
3276
JMP
RDDIR
0BI>B
A900
3277
FNSHFT
LDA
#0
0BI»D
A003
3278
FNSHFl
LDY
#3
0B9F
1E8113
3279
FNSHF2
ASL
FCBFNO.X
03 A 2
2A
3280
ROL
A
0BA3
88
3281
DEY
0BiV4
D0F9
3282
BNE
FNSHF2
0Bi\6
60
3283
RTS
•GET FILE NUMBER
;SET ACU=FILE NO/64
;T0 GET DIR SECTOR
;SET ACU TO REM=16
;T0 GET DIR DISPL
; SHIFT 3 BITS OF
;FILE NO INTO ACU
DEVICE DEPENDENT COMMAND
03 A 7
0BA7
0B.\A
0BAD
0BAF
03 Bl
03B3
0BB5
03 B6
0B38
0BBA
03 BB
03 BC
03 BF
03 C0
03C3
0BC4
206411
3D4203
C9FE
F025
C927
B01E
38
E920
9019
0A
A8
B9C50B
48
B9C60B
48
60
03C5
0BC7
0BC9
0BCB
03CD
03CF
0BD1
0027
0BD8
0C31
0BD2
0C7B
0C82
0C39
0D02
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
.PAGE "DEVICE DEPENDENT COMMAND"
DFMDDC - DEVICE DEPENDENT CMD EXECUTION
JSR
LDA
CMP
3EQ
CMP
3CS
SEC
SBC
BCC
ASL
TAY
LDA
PHA
LDA
PHA
RTS
SETUP
ICCOM.X
#254
XFV
♦MAXDDC
DVDCER
#S20
DVDCER
A
DVDCVT.Y
DVDCVT+1 , Y
;SET UP FOR EXECUTION
;GET COMMAND
;IS IT FORMAT
;BR IF
;TEST RANGE
;BR OUT OF RANGE
; SUBTRACT BASE OF CMDS
,-3R OUT OF RANGE
.-PUSH EXECUTION ADDR
. D3YTE XRENAME-1 ; 20-RENAME
. DBYTE XDELETE-1 ;21-DELETE
. DBYTE DVDCER-1 ; INVALID CMD
.DBYTE XLOCK-1 ;23-LOCK
.DBYTE XUNLOCK-1 ; 24-UNLOCK
. DBYTE XPOINT-1 ;25-POINT
.DBYTE XNOTE-1 ; 26-NOTE
MAXDDC
S27
;MAX DVDC+1
75
ATARI DOS 2.0S
3316 ;
0BD3 4CBF12 3317 DVDCER JMP ERDVDC
0BD6 4C180D 3318 XFV JMP XFORMAT
; FORMAT VECTOR
RENAWE
0BD9
0BD9 209E0E
0BDC 8C0D13
0BDF 20210F
0BE2 9003
0BE4 4CBB12
0BE7 20AC0C
0BEA 209B12
0BED D003
0BEF 201912
.PAGE "RENAME"
XRENAME - RENAME A FILE OR FILES
0BF2
0BF5
0BF8
0BFB
0BFD
0C00
0C03
0C04
0C07
0C08
0C09
AC0D13
20B40E
209B12
D00F
AC0513
B90514
48
B90414
A8
68
205312
0C0C A200
0C0E AC0513
0C11 BD5913
0C14 C93F
0C16 F003
0C18 990614
0C1B C8
0C1C E8
0C1D E00B
0C1F 90F0
0C21 AE0113
0C24 207110
0C27 209E0E
0C2A 20310F
0C2D 90B8
0C2F 4CEA12
3319
3320
3321
3322
3323 XRENAME
3324
3325
3326
3327
3328
3329 ;
3330 XRNl
3331
3332
3333
3334 XRNIA
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346 ;
3347 XRNIB
3348
3349
3350 ;
3351 XRN2
3352
3353
3354
JSR
STY
JSR
BCC
JMP
JSR
JSR
BNE
JSR
LDY
JSR
JSR
BNE
LDY
LDA
PHA
LDA
TAY
PLA
JSR
LDX
LDY
LDA
CMP
BEQ
STA
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
XRN3
FNDCODE
TEMP2
SFDIR
XRNl
ERFNF
TSTLOCK
TSTDOS
XRNIA
DELDOS
TEMP2
FNDCNX
TSTDOS
XRNIB
CDIRD
FILDIR+DFDSSN+1 , Y
FILDIR+DFDSSN.Y
;A,Y NEW DOS
; DECODE FILE NAME
;SAVE FNAME INDEX
;GO FINE FILE IN DIR
;BR IF FOUND
;TEST LOCK
; IF NOT DOS
fTHEN
; DON'T CHANGE SO
;GET INDEX FOR END FNl
;G0 DECODE NEXT FILE NAME
;IF NOT DOS
;THEN
SETDSO
rGO WRITE SECTOR ZERO
#0
CDIRD
FNAME, X ;MOVE FILE NAME
#'7 ;FROM FNAME TO DIR ENT
XRN3 ;BUT DON'T CHANGE WILD CARD
FILDIR+DFDPFN,Y ;CHARS INDICATED IN
FNAME
INY
INX
CPX #11
BCC XRN2
LDX CURFCB
JSR WRTDIR
JSR FNDCODE
JSR CSFDIR
BCC XRNl
JMP FGREAT
; RESTORE X-REG
;G0 WRITE CIR DIR RECORD
;GET OLD FILENAME AGAIN
;CONTINUE SEARCH OF DIR
;BR IF FOUND ANOTHER
fGO TO GOOD ENDING
.PAGE "DELETE"
DELETE
0C32 3368
3369 ;
3370 ; XDELETE - DELETE ALL FILENAMES THAT MATCH
3371 ;
3372 XDELETE
0C32 209E0E 3373 JSR
0C35 20210F 3374
JSR
FNDCODE
SFDIR
;G0 DECODE FILENAME
r SEARCH DIR FOR FILENAME
76
ATARI DOS 2.0S
0C38
B03F
3375
BCS
DFNF
0C3A
3376
XDELX
=
*
0C3A
20530C
3377
JSR
XDEL0
0C3D
209B12
3378
JSR
TSTDOS
0C40
D003
3379
BNE
XDELY
0C42
201912
3380
3381
3382
XDELY
JSR
DELDOS
0C45
207110
3383
XDEL3
JSR
WRTDIR
0C48
20310F
3384
JSR
CSFDIR
0C4B
90ED
3385
BCC
XDELX
0C4D
209510
3386
JSR
WRTVTCX:
0C50
4CEA12
3387
3388
,
JMP
FGREAT
0C53
20BF10
3389
3390
XDEL0
JSR
OPVTOC
0C56
AC0513
3391
XDELl
LDY
CDIRD
0C59
20AC0C
3392
JSR
TSTLOCK
0C5C
A980
3393
LDA
tDFDEDE
0C5E
990114
3394
3395
,
STA
FILDIR+DFl
0C61
20AE09
3396
JSR
DFRDSU
0C64
4C6C0C
3397
3398
.
JMP
XDEL2A
0C67
200F10
3399
XDEL2
JSR
RDNXTS
0C6A
B006
3400
BCS
XDEL4
0C6C
3401
XDEL2A
=
*
0C6C
20C510
3402
JSR
FRESECT
0C6F
4C670C
3403
3404
.
JMP
XDEL2
0C72
3405
XDEL4
=
*
0C72
A005
3406
LDY
#DVDWRQ
0C74
A9FF
3407
LDA
#$FF
0C76
9145
3408
STA
(ZDRVA),Y
0C78
60
3409
3410
:
RTS
0C79
4CBB12
3411
DFNF
JMP
ERFNF
;BR NOT FOUND
WRITE DIR ENTRY
LOOK FOR NEXT MATCH
BR IF FOUND
;GET DIR DISPL
;G0 TEST LOCK
;LOAD DELETED FLAG
FL1,Y rDELETE FILE
;READ NEXT SECTOR
;FREE CURRENT SECTOR
rTURN ON WRITE REQ ' D
;FILE NOT FOUND
UCK AND UNLOCK
0c:7c
3412
.PAGE "LOCK AND
UNLOCK"
3413
•
3414
; XLOCK - LOCK A FILE
3415
; XUNLOCK -
UNLOCK A FILE
3416
3417
XLOCK
0<:7C
A920
3418
LDA
tDFDLOC
r SET LOCK
0<:7E
8D0F13
3419
STA
TEMP4
0(:81
D005
3420
BNE
XLCOM
•GO TO COMMON
3421
XUNLOCK
0C83
A900
3422
LDA
#0
:SET UNLOCK
0<:85
8D0F13
3423
3424
,
STA
TEMP4
0(:88
209E0E
3425
XLCOM
JSR
FNDCODE
; DECODE FILE NAME
0<:8B
20210F
3426
JSR
SFDIR
;FIND 1ST MATCH
0C8E
9003
3427
BCC
XLCl
rBR MATCH FOUND
0(:90
4CBB12
3428
3429
.
JMP
ERFNF
;BR NOT FOUND
0(:93
AC0513
3430
XLCl
LDY
CDIRD
;GET CURRENT DISPL
0C96
B90114
3431
LDA
FILDIR+DFDFLl.Y ;GET LOCK BYTE
0(:99
29DF
3432
AND
#$DF
rTURN OFF LOCK
0C9B
0D0F13
3433
ORA
TEMP4
;0R IN LOCK/UNLOCK
0C9E
990114
3434
STA
FILDIR+DFDFLl.Y rSET NEW LOCK
0(:ai
207110
3435
3436
,
JSR
WRTDIR
;G0 WRITE
0CA4
20310F
3437
JSR
CSFDIR
;LOOK FOR NEXT MATCH
0CA7
90EA
3438
BCC
XLCl
;BR FOUND
77
ATARI DOS 2.0S
0CA9 4CEA12 3439 JMP FGREAT ;ELSE DONE
3440 ;
3441 ; TSTLOCK - TEST FILE LOCKED
3442 ;
3443 TSTLOCK
0CAC AC0513 3444 LDY
0CAF B90114 3445 LDA
0CB2 2920 3446 AND
0CB4 D001 3447 BNE
0CB6 60 3448 RTS
3449 ;
0CB7 4CC112 3450 TLF JMP ERFLOCK
CDIRD ;GET DIR DISPL
FILDIR+DFDFLl.Y ;LOAD LOCK BYTE
♦DFDLOC ;MASK LOCK BIT
TLF ;BR IF LOCKED
POINT
0CBA
3451
.PAGE "POINT"
3452
•
3453
; XPOINT -
POINT REQUEST
3454
;
3455
XPOINT
0CBA
BD8513
3456
LDA
FCBFLG,X
;IF ARQ SECTORS
0CBD
3041
3457
BMI
PERRl
; POINT INVALID
0CBF
BD4D03
3458
LDA
ICAUX4,X
;IF REQUEST IS NOT
0CC2
DD8A13
3459
CMP
FCBCSN+1 ,
X ;SAME AS CURRENT
0CC5
D008
3460
BNE
XPl
;THEN BR
0CC7
BD4C03
3461
LDA
ICAUX3,X
0CCA
DD8913
3462
CMP
FCBCSN.X
0CCD
F01E
3463
3464
;
BEQ
XP2
jELSE NO NEED TO CI
0CCF
BD8513
3465
XPl
LDA
FCBFLG.X
;IF NOT MODIFIED
0CD2
F008
3466
BEQ
XPIA
;BR
0CD4
20P80F
3467
JSR
WRCSIO
;ELSE WRITE IT
0CD7
A900
3468
LDA
#0
0CD9
9D8513
3469
STA
FCBFLG.X
0CDC
3470
XPIA
s
*
0CDC
BD4D03
3471
LDA
ICAUX4,X
0CDF
9D8C13
3472
STA
FCBLSN+1,
X
0CE2
BD4C03
3473
LDA
ICAUX3,X
0CE5
9D8B13
3474
STA
FCBLSN.X
0CE8
201710
3475
JSR
RDNSO
;READ REQ SECTOR
0CEB
B00A
3476
3477
.
BCS
XPERR
0CED
BD4E03
3478
XP2
LDA
ICAUX5,X
;TEST REQ DATA LEN
0CF0
DD8613
3479
CMP
FCBMLN.X
;LESS THEN MAX
0CF3
9005
3480
BCC
XP3
0CF5
F003
3481
BEQ
XP3
0CF7
3482
XPERR
=
*
0CF7
4CC312
3483
3484
,
JMP
ERRPDL
;IF NOT THEN ERROR
0CFA
9D8713
3485
XP3
STA
FCBDLN.X
;SET NEW DATA LEN
0CFD
4CF012
3486
3487
;
JMP
GREAT
0D00
4CB912
3488
PERRl
JMP
ERRPOT
0D03
3489
.PAGE "NOTE"
3490
;
3491
; XNOTE - EXECUTE NOTE
REQUEST
3492
;
3493
XNOTE
0D03
BD8713
3494
LDA
FCBDLN.X
fDATA LENGHT VALUE
0D06
9D4E03
3495
STA
ICAUX5,X
;T0 AUX 2
0D09
BD8913
3496
LDA
FCBCSN.X
;CUR SEC NO (LO)
0D0C
9D4C03
3497
STA
ICAUX3.X
J TO AUX 3
0D0F BD8A13 3498
LDA FCBCSN+1. X ;CUR SEC NO (HI)
78
ATARI DOS 2.0S
0D:.2 9D4D03 3499
0d:.5 4CF012 3500
STA
JMP
ICAUX4,X
GREAT
;T0 AUX 4
P01«1AT
0D:L8
3501
.PAGE "FORMAT"
3502 ;
3503 ; XFORMAT
3504 ;
3505 XFORMAT
0D18
0DIA
0DLD
0DLF
0D22
0D:24
00 27
0D29
0D2C
0D2F
0D31
0D34
0d:)7 1019
0D;)9 C090
0d:)B D012
0D:iD
0D3D A000
0D:JF B147
0D41 C9FF
0D43 D007
0D45 C8
0D46 B147
0D48 C9FF
0DIA F003
0DtC 4CB512
0DtF 4CD312
0D52 A900
0D54 A8
0D55 9145
0D57 C8
0D58 10FB
0D5A
0D5C
0D5E
0D60
0DS1
0D63
0D65
0D66
0D67
A000
A902
9145
C8
A9C3
9145
C8
ce
9145
FORMAT A DISKETTE
A548
8D0503
A547
8D0403
A921
8D0203
A940
8D0303
AEFE12
A931
AC4602
208607
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518 ;
3519
3520
3521
3522 ;
3523 TSTFMT
3524
3525
3526
3527
3528
3529
3530
3531
3532 XFBAD
3533 ;
3534 XFERR
3535 ;
3536 XF0
3537
3538
3539 XFl
3540
3541
3542 ;
3543
3544
3545
3546
3547
3548
3549
3550
3551
LDA
STA
LDA
STA
LDA
STA
LDA
STA
LDX
LDA
LDY
JSR
BPL
CPY
BNE
LDY
LDA
CMP
BNE
INY
LDA
CMP
BEQ
JMP
LDA
TAY
STA
INY
BPL
LDY
LDA
STA
INY
LDA
STA
INY
INY
STA
ZSBA+1
DCBBUF+1
ZSBA
DCBBUF
♦DCBCFD
DCBCMD
#$40
DCBSTA
DRVTYP
#$31
DSKTIM
DSI02
XF0
#$90
XFERR
#0
(ZSBA),Y
#$FF
XFBAD
(ZSBA),Y
#$FF
XFERR
ERDBAD
;MOVE VTOC BUF ADR
;T0 DCB
J FORMAT
;T0 DCB
;TELL SIO RECIEVING DATA
;GET DR TYPE 128 OR 256
jBUS I.D.
;GET FORMAT TIME OUT VALUE
;GOTO LOCAL DISK HANDLER THEN
SIO
; IF NO ERRORS CONT FORMATING
;ELSE CK FOR DEVICE DONE ERROR
;N0, THEN ERROR EXIT
•ELSE CK FOR BAD SECTOR INFO
; RETURNED BY CONTROLLER
;BAD SECTORS RET ERR MSG
;NOT BAD SEC ERR, REQ ERR EXIT
JMP RETURN
;DO ERROR EXIT
#0
(ZDRVA),Y
XFl
#0 ;SET
#2 ;TYPE = 2
(ZDRVA),Y
#$C3 ;SET MSN AND
(ZDRVA),Y ;NSA=107=2C3
(ZDRVA),Y
FORMAT
0E69 A902
0D6B 88
0D6C 9145
0E6E C8
0E6F C8
0E70 9145
3552
3553
3554
3555
3556
3557
LDA #$02
DEY
STA (ZDRVA),Y
INY
INY
STA (ZDRVA),Y
79
ATARI DOS 2.0S
3558
;
0D7::
A00A
3559
LDY
#DVDSMP
0D74
A9FF
3560
LDA
#$FF
;SET SECTOR MAP TO
0D7f,
9145
3561
XF2
STA
(ZDRVA),y
;ALL ONES
0D7EI
C8
3562
INY
0D7?i
C064
3563
CPY
#DVDSMP+90
0D7E1
D0F9
3564
3565
,
BNE
XF2
0D7D
A90F
3566
LDA
#50F
JDEALOCATE 1ST 4 SECTORS
0D7F
A00A
3567
LDY
fDVDSMP
;FOR BOOT
0D81
9145
3568
3569
?
STA
(ZDRVA),Y
0D8;i
A037
3570
LDY
#DVDSMP+45
; DEALLOCATE MIDDLE 9
0D8!.
A900
3571
LDA
#0
0D8T
9145
3572
STA
(ZDRVA),Y
;FOR
0D8?'
C8
3573
INY
jVTOC AND FILE DIR
0D8;i.
A97F
3574
LDA
#$7F
0D8C
9145
3575
3576
,
STA
(ZDRVA),Y
0D8e:
209510
3577
3578
,
JSR
WRTVTOC
•WRITE THE VTOC
0D9]
A900
3579
LDA
#0
;0 FILLE DIR SECTORS
0D9;
A8
3580
TAY
0D94
990114
3 581
XF3
STA
FILDIR.Y
;USE FILE DIR BUFFER
0D97
C8
3582
INY
0D9f:
10FA
3583
3584
.
BPL
XF3
0D9;i
A907
3585
LDA
#7
•WRITE TO ALL 8 DIR SECT
0D9C
8D0613
3586
STA
CDIRS
0091'
207110
3587
XF4
JSR
WRTDIR
0DA2
CE0613
3588
DEC
CDIRS
0DAE
10F8
3589
3590
;
BPL
XF4
0DA-
201912
3591
3592
;
JSR
DELDOS
•SET NO DOS
0DAA
4CEA12
3593
JMP
FGREAT
•DONE
LIST
DIRECTORY
0DA1D
3594
.PAGE "LIST DIRECTORY"
3595
!
3596
; LISTDIR -
■ LIST THE DIRECTORY
3597
; GDCHAR -
GET NEXT DIR CHARACTER
3598
: THE
DIRECTORY IS LISTED VIA OPEN
3599
; LIST
DIRECTORY FUNCTION EACH DIR
3600
; ENTRY THAT MATCHES THE FILE SPEC
3601
; IS CONVERTED TO A PRINTABLE FORMAT
3602
; INTO
A SECTOR BUFFER
THE GET BYTE
3603
; ENTRY IS
USED TO GET
THE PRINTABLE
3604
; CHARACTERS ONE AT A
TIME. THE
3605
; LAST
LINE PRINTED IS
ALWAYS A
3606
; COUNT OF
THE NUMBET
OF SECTORS IN USE
3607
; AND
THE NUMBER REMAINING AVAILABLE SECTORS
3608
;
3609
LISTDIR
0DA1)
A900
3610
LDA
#0
0DA]?
8D0F13
3611
STA
TEMP4
0db:2
20210F
3612
JSR
SFDIR
.•SEARCH FOR A FILE NAME
0db:5
902C
3613
BCC
LDENTl
;BR IF FOUND
0DB7
B030
3614
3615
3616
GDCHAR
BCS
LDCNT
;BR IF NOT FOUND
0DB9
2C0F13
3617
BIT
TEMP4
;TEST FLAG
0DB<;
3053
3618
3619
.
BMI
LDDONE
;BR IF ALL DONE
0DB1?
AC0F13
3620
LDY
TEMP4
;GET COUNT OF CHARS SENT
0dc:l
B147
3621
LDA
(ZSBA),Y
;GET NEXT CHAR
80
ATARI DOS 2.0S
0DC3
8D0813
3622
STA
SVDBYT
; IN SVDBYT
BDce
EE0F13
3623
INC
TEMP4
;INC COUNT
0DC9
C99B
3624
CMP
#EOL
;TEST IF EOL DONE
0d<:b
D009
3625
BNE
GDCRTN
;BR NOT EOL
0DCD
C011
3626
CPY
#17
rWAS THIS AN ENTRY
0D(:f
B008
3627
BCS
LDENT
;BR IF IT WAS
0D131
A980
3628
LDA
#S80
;ELSE INDICATE END
0DD3
8D0F13
3629
3630
.
STA
TEMP4
;IN TEMP4
0DD6
4CF012
3631
3632
GDCRTN
JMP
GREAT
;DONE
0DD9
A900
3633
LDENT
LDA
#0
r CLEAR CHAR COUNTER
0DDB
8D0F13
3634
STA
TEMP4
0DDE
20310F
3635
JSR
CSFDIR
r SEARCH FOR NEXT MA'
0D:51
B00e
3636
3637
LDENTl
BCS
LDCNT
;BR NO MORE MATCHES
0D33
20210E
3638
JSR
FDENT
; FORMAT ENTRY
0D136
4CF012
3639
3640
,
JMP
GREAT
;DONE
0D]39
208B10
3641
LDCNT
JSR
RDVTOC
;READ VTOC
0d:3c
A004
3642
LDY
♦DVDNSA+1
;GET # SECTOR AVR
00)! E
B145
3643
LDA
(ZDRVA),Y
0d:?0
48
3644
PHA
LIST DIRECTORY
0DP1 88
0DF2 B145
0DF4 A8
0DF5 68
0DF6 20570E
0DF9 A003
0DFB A20C
0DFD BD140E
0E00 9147
0E02 C8
0E03 CA
0E04 10F7
0E06 20670E
0E09 A900
0E0B 8D0F13
0E0E 4CEA12
0E11 4CF412
0E14 53
0E15 52
0E16 4F
0i;i7 54
0E;18 43
0e;19 45
0i;iA 53
0b:ib 20
0B:1C 45
0b;id 45
0E1E 52
0E1F 46
0e:20 20
000D
0i;2i
0i;21
3645
3646
3647
3648
3649 ;
3650
3651 ;
3652
3653
3654 MVFSCM
3655
3656
3657
3658
3659
3660 ;
3661
3662
3663
3664 ;
3665 LDDONE
3666
3667 ;
3668 FSCM
DEY
LDA (ZDRVA),Y
TAY
PLA
JSR CVDX
LDY #3
LDX #FSCML-1
LDA FSCM.X
STA (ZSBA),Y
INY
DEX
BPL MVFSCM
JSR CVDY
LDA #0
STA TEMP4
JMP PGREAT
jAND CONVERT
;SET EOL
rPUT IN CUTE
; MSG
SET CHAR CNT
JMP ERREOF ;END OF FILE
.BYTE "SROTCES EERF "
3669 FSCML = *-FSCM
35 .INCLUDE #E:
40 .INCLUDE #D:ATFMS3.
SRC
81
ATARI DOS 2.0S
LIST DIRECTORY
0E21
4000
4001
4002
4003
4004
0E2L
A000
4005
0E2 3
A920
4006
0E25
9147
4007
0E2 7
AE0513
4008
0E2i\
BD0114
4009
0E2D
2920
4010
0E2ir
F004
4011
0E31
A92A
4012
0E3:3
9147
4013
0E3!;
C8
4014
0E3i5
A920
4015
0E3I3
9147
4016
0E3A
C8
4017
4018
0E3I!
BD0614
4019
0E31i;
9147
4020
0E4I!I
E8
4021
0E4;.
C8
4022
0E4:>
C00D
4023
0E44
90F5
4024
4025
0E4(i
A920
4026
0E4(i
9147
4027
0E4A
C8
4028
0E4H
8C0F13
4029
4030
0E4i;
AE0513
4031
0E5].
BC0214
4032
0E54
BD0314
4033
4034
4035
0E57
A264
4036
0E59
20710E
4037
0E5C;
A20A
4038
0E5i;
20710E
4039
0E6].
98
4040
0E6::
208D0E
4041
4042
0E6!i
A011
4043
0E67
A99B
4044
0E6S'
9147
4045
0E6Ei
A000
4046
0E6r>
8C0F13
4047
0E7e'
60
4048
4049
0E71
8E0E13
4050
.PAGE
; FORMAT DIR ENTRY INTO A SECTOR BUFFER
FDENT
LDY #0
LDA *$20
STA (ZSBA),Y
LDX CDIRD
LDA FILDIR+DFDFLl.X
AND #DFDLOC ;BUT IF FILE LOCKED
BEQ LDl
LDA # ' *
STA (ZSBA),Y
INY
LDA #$20
STA (ZSBA),Y
INY
; START AT DISPL ZERO
; START WITH A BLANK
; CHANGE TO AST
J FOLLOWED BY A BLANK
LD2
LDA FILDIR+DFDPPN,X ;MOVE THE 12 CHAR
STA (ZSBA),Y ;FILE NAME
I NX
INY
CPY #13
BCC LD2
LDA #S20
STA (ZSBA),Y
INY
STY TEMP4
.•FOLLOWED BY A BLANK
;SAVE INDEX =15
LDX CDIRD
LDY PILDIR+DFDCNT,X ;SET A,Y
LDA FILDIR+DFDCNT+1,X r=SECTOR COUNT
LDX #100
JSR CVDIGIT
LDX #10
JSR CVDIGIT
TYA
JSR STDIGIT
LDY #17
LDA #EOL
STA (ZSBA),Y
LDY #0
STY TEMP4
RTS
CVDIGIT STX TEMP3
CVDY
; CONVERT AND MOVE
;100S DIGIT
;10S DIGIT
;1S DIGIT
;THEN PUT OUT
;AND EOL
;SET CHAR CNT =
rSAVE DIGIT VALUE
LIST DIRECTORY
0E74 A2FF
4051
4052 ;
LDX
#SFF
0E76 8D0D13
4053 CVDl
STA
TEMP2
;SAVE CURR VALUE HI
0E79 8C0C13
4054
STY
TEMPI
?AND LOW
0E7C E8
4055
INX
; INC DIGIT COUNTER
0E7n 38
4056
SEC
JSUBRTACT DIGIT VAU
0E7E AD0C13
4057
LDA
TEMPI
;PROM CUR VALUE
0E81 ED0E13
4058
SBC
TEMP3
0E84 AS
4059
TAY
0E85 AD0D13
4060
LDA
TEMP2
0E88 E900
4061
SBC
#0
82
ATARI DOS 2.0S
0E8A
B0EA
4062
4063
BCS
CVDl
0E8(:
8A
4064
TXA
0E8I)
0930
4065
STDIGIT ORA
#?30
0E81?
AC0F13
4066
LDY
TEMP4
0E9:J
9147
4067
STA
(ZSBA),Y
0E94
EE0F13
4068
INC
TEMP4
0E97
AD0D13
4069
LDA
TEMP2
0E9A
AC0C13
4070
LDY
TEMPI
0E915
60
4071
RTS
;IF NOT GONE MINUS, DO AGAIN
; DIGIT TO ACU
;PLUS ASCII ZERO
;GET OUTPUT INDEX
;AND SET DIGIT
; INC OUTPUT INDEX
;LOAD VALUE HI
;AND VALUE LO
FILE NAME DECODE
0E9E
0E9E BD4403
0EA1 8543
0EA3 BD4503
0EA6 8544
0EAB A002
0EAh B143
88
3058
C93A
D0F7
0EAC
0EAD
0EAF
0EB1
0EB3 C8
0EB4 A20B
0EB6 A920
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
.PAGE "FILE NAME DECODE"
FNDCODE - DECODE A FILE NAME
THE USER FILENAME IS POINTED TO BY
ZBUFP, IT IS ON THE FORM P.X WHERE P
IS THE PRIMARY FILE NAME (1 TO 8 CHARS)
AND X IS THE EXTENDED FILE NAME
(0 TO 4 CHARS). THE PERIOD IS OPTIONAL
(IF NOT PRESENT, THEN NO EXTENSION).
THE DECODED FILENAME WILL BE 12 CHARS
IN LENGTH. THE P FIELD WILL BE
LEFT JUSTIFIED IN THE 1ST 8 BYTES.
THE X FIELD WILL BE LEFT JUSTIFIED IN
THE LAST 4 BYTES. BLANKS ARE USED
TO PAD THE FIELDS TO FULL SIZE.
IF THE USER SPECIFIED P OR X FILEDS
CONTAIN MORE THAN 8 OR 4 CHARS, THEN THE
EXTRA CHARS ARE IGNORED. THE '*'
WILD CARD CHAR WILL CAUSE THE REST
OF THE FIELDS TO FILLED WITH THE
'?■ WILD CARD CHAR. ANY NON-ALPHANUMERIC
CHAR TERMINATES THE FILENAME.
FNDCODE
FD0A
FD0B
FNDCNX
LDA
ICBAL,X
STA
ZBUFP
LDA
ICBAH,X
STA
ZBUFP+1
LDY
#2
;FIND THE
LDA
( ZBUFP ),Y
DEY
BMI
FNDERR
;BR IF 25
CMP
#' :
BNE
FD0A
■D'
LDX
LDA
#11
*$20
0EB8 9D5913 4113 FD0
4114
4115
4116 ;
0EBE A200 4117
0EC0 8E0C13 4118
4119 ;
4120 ;
4121 FDl
4122
0EBB CA
0EBC 10FA
0EC3 C8
0EC4 B143
STA FNAME,X
DEX
BPL FD0
LDX #0
STX EXTSW
r CLEAR FILENAME TO BLANKS
;SET FNAME CHAR CNT TO
;SET NOT IN EXTENSION
INY
LDA
;INC ZBUFP INDEX
(ZBUFP), Y rGET BUF CHAR
83
ATARI DOS 2.0S
FILE NAME DECODE
4123
;
0EC6
C92A
4124
CMP
#'* •
0EC8
D00B
4125
4126
;
BNE
Fr3 ;
0ECA
A93F
4127
FD2
LDA
#'? ;
0ECC
200A0F
4128
JSR
FDSCHAR ;
0ECF
90F9
4129
BCC
FD2 ;
0ED1
10F0
4130
BPL
FDl ;
0ED3
302E
4131
4132
,
BMI
FDEND ;
0ED5
C92E
4133
FD3
CMP
#•• :
0ED7
D00C
4134
BNE
FD4 ;
0ED9
2C0C13
4135
BIT
EXTSW
0EDC
3025
4136
BMI
FDEND ;
0EDE
A208
4137
LDX
#8 ;
0EE0
6E0C13
4138
ROR
EXTSW
0EE3
90DE
4139
4140
,
BCC
FDl ;
0EE5
C93F
4141
FD4
CMP
#'? W
0EE7
F014
4142
4143
,
BEQ
FD6 ;
0EE9
C941
4144
CMP
#'A ;
0EEB
9004
4145
BCC
FD5
0EED
C95B
4146
CMP
#$5B ;
0EEF
900C
4147
4148
;
BCC
FD6 ;
0EF1
E000
4149
FD5
CPX
#0
0EF3
F012
4150
4151
;
BEQ
FNDERR
0EF5
C930
4152
CMP
#$30
0EF7
900A
4153
BCC
FDEND
0EF9
C93A
4154
CMP
#$3A ;
0EFB
B006
4155
4156
,
BCS
FDEND ;
0EFD
200A0F
4157
FD6
JSR
FDSCHAR r
0F00
4CC30E
4158
4159
.
JMP
FDl :
0F03
AE0113
4160
FDEND
LDX
CURFCB ;
0F06
60
4161
4162
r
RTS
0F07
4CC512
4163
FNDERR
JMP
ERRFN
TEST FOR WILD CARDS
BR NOT WILD CARD
LOAD 7 WILD CARD
GO STORE IT
BR IF PORX NOT FULL
BR IF AT START OF X
BR IF AT X END
WAS CHAR FIELD SEPERATOR
BR IF NOT
WAS THERE ALREADY 1 CHAR
BR IF WAS END
ADV FNAME INDEX TO XFIELD
SET EXTSW - MINUS
CONT WITH NEXT CHAR
WAS IT WILD CARD
BR IF WILD CARD
IS CHAR ALPHA
BR NOT ALPHA
TEXT HI ALPHA
BR IF NOT APLHA
IF FIRST CHAR NOT
ALPHA THEN ERROR
IS CHAR NUMERIC
BR NOT NUMERIC (END OF NAME)
TEST NUMERIC HI
BR NO NUMBER
STORE THE CHAR
AND CONTINUE WITH NEXT
RESTORE X REG
INDICATE FILENAME ERROR
FMS - 128/256 BYTE SECTOR (2.0S)
FILE NAME DECODE
0F0A
4164
.PAGE
4165
4166
; FDSCHAR -
STORE FILENAME CHAR
4167
4168
; ON ENTRY
4169
; A = CHAR
4170
; X = NEXT
FN POSITION
4171
4172
; ON EXIT
4173
; CARRY - SET IF FIELD FULL
4174
; MINUS - IF START OF EXECUTION
4175
; PLUS - IF END OF EXECUTION
4176
;
4177
FDSCHAR
0F0A
E008
4178
CPX
#8 ;AT EXECUTION
0F0C
900D
4179
BCC
FDSC2 ;BR IF NOT
0F0E
F005
4180
4181
BEO
FDSCl ;BR IF 1ST
CHAR OF
0F10
E00C
4182
CPX
#12 ;AT END OF
EXIT
0F12
9007
4183
BCC
FDSC2 ;BR NOT AT
END
84
ATARI DOS 2.0S
0F14 60
4184
4185 (
RTS
0F15 2C0C13
4186 FDSCl
BIT
EXTSW
0F18 3001
4187
BMI
FDSC2
0F1A 60
4188
4189 ;
RTS
0F1B 9D5913
4190 FDSC2
STA
FNAME.X
0F1E E8
4191
INX
0F1F 18
4192
CLC
0F20 60
4193
RTS
;DO NOT STORE CHAR UNLESS
; PERIOD WAS SEEN
;SET CHAR INTO NAME
;INC TO NEXT CHAR
DIRECTORY SEARCH
0F21
4194
.PAGE "DIRECTORY SEARCH"
4195 ,
4196 ;
SFDIR - SEARCH FILE
DIRECTORY
4197
CSFDIR - FILE DIRECTORY SEARCH
4198
4199
THE
FILE DIRECTORY
IS SEARCHED FOR THE
4200
FILENAME IN FNAME .
THE SEARCH STARTS
4201
AT THE CENTRAL SECTOR+1 AND WILL CONTINUE
4202
FOR
UP TO
A TOTAL OF 8 SECTORS. WHEN
4203
TESTING FOR FNAME MATCH, '7' FNAME
4204
CHARS WILL ALWAYS MATCH THE CORESPONDING
4205
DIR
FILENAME CHAR.
IF A MATCH IS FOUND
4206
CDIRS CONTAINS THE
RELATIVE DIRECTORY SECTOR
4207
NUMBER (0
-7) AND CDIRD (AND THE Y REG)
4208
CONTAINS THE DISPLACEMENT OF THE ENTRY.
4209
AFTER A MATCH HAS BEEN FOUND, THE DIRECTORY CAN
4210
BE SEARCHED FOR ANOTHER MATCH VIA THE CSFDIR
4211
ENTRY POINT. IF A
MATCH HAS NOT BEEN FOUND
4212
THEN DHOLES AND DHOLED WILL POINT TO A
4213
DIRECTORY
HOLE THAT
CAN BE USED.
4214
• IF DHOLED
= FF THEN THE DIRECTORY IS FULL.
4215
THE
CARRY
IS RETURNED CLEAR IF FILE FOUND,
4216
SET
IF FILE NOT FOUND.
4217
4218
3FDIR
0F21
A9FF
4219
LDA
#$FF
;INIT TO -1
0F23
8D0213
4220
STA
DHOLES
;DIR HOLE SECTOR
0F26
8D0613
4221
STA
CDIRS
;CUR DIR SECTOR
0F29
8D0713
4222
STA
SFNUM
;FILE NUMBER
0F2C
A970
4223
LDA
#570
;INIT TO -16 (-ENTRY LENGTH)
0E2E
8D0513
4224
4225
•
STA
CDIRD
;CUR DIR DISPL
4226
::sFDiR
0F31
EE0713
4227
INC
SFNUM
0F34
18
4228
CLC
0F35
AD0513
4229
LDA
CDIRD
;CDIRD=CDIRD+ENTRY LEN
0S38
6910
4230
ADC
#DFDELN
0B3A
1011
4231
BPL
SFD2
;IF RESULT <128 THEN BR
4232
; ELSE AT END OF DIR
SECT
0F3C
EE0613
4233
INC
CDIRS
,-INC TO NEXT DIR SECTOR
0F3F
A908
4234
LDA
#8
;TEST END OF DIR
0F41
CD0613
4235
CMP
CDIRS
0F44
9002
4236
BCC
SPDl
;BR NOT END
0F46
F048
4237
4238
BEQ
SDRTN
0F48
206E10
4239
3FD1
JSR
RDDIR
;READ THE NEXT DIR RECORD
0S'4B
A900
4240
4241
,
LDA
#0
;SET DIR DISPL =
0I'4D
8D0513
4242
SFD2
STA
CDIRD
;SET NEW DIR DISPL
0F50
A8
4243
4244
r
TAY
;PUT DISPL IN Y AS INDEX
85
ATARI DOS 2.0S
DIRECTORY SEARCH
0F5;.
0F54
0F5<i
0F5B
0F5/1
B90114
F01D
301B
2901
D0D5
0F5C
0F5i:
0F6]
0F6;i
0F6;;
0F6£:
0F6;i.
0F6E.
0F6C
0F6F
0F7ei
0F73
0F73
0F7fi
0F761
0F7E:
0F7E;
0F81
0F84
0F87
0F8f.
0F8ri
A200
BD5913
C93F
F005
D90614
D0C7
E8
C8
E00B
D0EE
18
901D
AD0213
1012
AD0613
8D0213
AD0513
8D0313
AD0713
8D0413
B90114
30A2
0F8F 38
0F90
0F93
AE0113
60
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
LDA FILDIR+DFDFLl.Y :GET FLAG 1
BEQ SFDSH ;BR IF UNUSED (END OF USED
ENTRIES)
BMI SFDSH ;BR IF DELETED
AND #DFDOUT ;IF OPEN OUTPUT
BNE CSFDIR ;DON'T FIND IT
ENTRY IN USE, TEST FOR MATCH
SFD3
SFD4
LDX
LDA
CMP
BEQ
CMP
BNE
INX
INY
CPX
BNE
CLC
BCC
LDA
BPL
#0 ;TEST MATCH ON 12 CHARS
FNAME.X ;FILE NAME CHAR
#'7 ;IS FNC WILD CARD
SFD4 ;THEN IT MATCHES
FILDIR+DFDPFN.Y ;ELSE IT MUST MATCH FOR
REAC
CSFDIR ;IF NOT MATCH THEN TRY NEXT
;INC CHAR CNT
; ELSE
LDA
STA
LDA
STA
LDA
STA
SFDSHl LDA
BMI
#11
SFD3
SDRTN
DHOLES
SFDSHl
CDIRS
DHOLES
CDIRD
DHOLE D
SFNUM
DHFNUM
;TEST ALL
rAND CONTINUE CHECK
;WE HAVE A MATCH
rIF DHOLES NOT MINUS
;THEN ALREADY HAVE A GOOD HOLE
;MOVE CURR DISPL SECTOR
;AND CURRENT DIR DISPL
;T0 HOLE SECTOR AND DISPL
;SAVE HOLE
;FILE NUMBER
FILDIR+DFDFLl.Y ;IF HOLE WAS A DELETED
CSFDIR : ENTRY THEN CONTINUE
ELSE WE ARE AT END OF
SDRTN LDX CURFCB
RTS
;USED ENTRIES THUS FILE NOT
FOUND
: RESTORE X REG
WRITE DATA SECTOR
0F94
0F94
0F97
0F99
0F9A
0F9C
0F9E
0FAe
0FA3
0FA5
BD8513
300F
0A
1009
0A
9D8513
20F80F
3024
4C0F10
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
.PAGE "WRITE DATA SECTOR"
; WRTNXS - WRITE NEXT SECTOR
WRTNXS
LDA FCBFLG.X
BMI WRTNl
ASL
BPL
ASL
STA
JSR
BMI
WRUl JMP
A
WRUl
A
FCBFLG.X
WRCSIO
WRNERR
RDNXTS
;IF ACQUIRING SECTORS
fTHEN NOT UPDATE
;IF SECTOR NOT MODIFIED
;THEN DON'T IT
.•TURN OFF FLAG BITS
rWRITE CURRENT SECTOR
.•BR IF BAD I/O
;ELSE READ NEXT SECTOR
86
ATARI DOS 2.0S
0FAB
2006H
4304
4305
WRTNl
JSR
GETSECTOR
•GET A NEW SECTOR
0FAH
BD8713
4306
WRTLSEC LDA
FCBDLN.X
•GET DATA LEN
0FAIi;
ACFB12
4307
WRTLSl
LDY
DRVLBT
•INTO LAST BYTE
0fb:l
9147
4308
4309
.
STA
(ZSBA),Y
•OF SECTOR
0FB;i
BD8C13
4310
WRTN2
LDA
FCBLSN+1 , X
;MOVE LINK SECTOR
0FB(J
1D8113
4311
ORA
FCBFNO.X
•PLUS FILE NUM
0FB9
ACF812
4312
LDY
DRVMDL
•TO BYTES 126,127
0FB(:
9147
4313
STA
(ZSBA),Y
;0F SECTOR BUFF
0FB1S
C8
4314
INY
0FB1?
BD8B13
4315
LDA
FCBLSN.X
0FC:2
9147
4316
4317
,
STA
(ZSBA),Y
0FC4
20F80F
4318
JSR
WRCSIO
.•WRITE SECTOR
0FC7
1011
4319
4320
.
BPL
WRTN5
;BR NOT ERROR
0FC')
AD0303
4321
WRNERR
LDA
DCBSTA
rSAVE ERROR STATUS
0FC<:
8D0F13
4322
STA
TEMP4
0FC1?
A900
4323
LDA
#0
; CLOSE FILE
0FDL
9D8213
4324
STA
FCBOTCX
0FD4
AD0F13
4325
LDA
TEMP4
; RECOVER ERROR CODE
0FD7
4CD312
4326
4327
4328
!
WRTN5
JMP
RETURN
0FD,\
FE8F13
4329
INC
FCBCNT.X
:INC SECTOR CNT
0fd:3
D003
4330
BNE
WRTN6
0fd:?
FE9013
4331
4332
WRTN6
INC
FCBCNT+1 , X
0FE2
200210
4333
JSR
MVLSN
;LINK TO CUR
0FE5
A900
4334
LDA
#0
0FE7
9D8B13
4335
STA
FCBLSN.X
;LINK =
0FEA
9D8C13
4336
STA
FCBLSN+1, X
0FED
9D8713
4337
STA
FCBDLN.X
;DLN =
WRITE DATA SECTOR
0FFI3
ADF812
4338
LDA
DRVMDL
0FF3
9D8613
4339
4340
WRNRTS
STA
FCBMLN.X
0FF5
18
4341
CLC
0FF7
60
4342
4343
;
RTS
0FF3
38
4344
WRCSIO
SEC
;WRITE CUR
0FF9
BD8A13
4345
RWCSIO
LDA
FCBCSN+1,X
0ff:
BC8913
4346
LDY
FCBCSN.X
0FFF
4CF711
4347
4348
,
JMP
DSIO
1002
BDSBIS
4349
MVLSN
LDA
FCBLSN.X rMOVE LINK
1005
9D8913
4350
STA
FCBCSN.X
100B
BD8C13
4351
LDA
FCBLSN+1, X
100B
9D8A13
4352
STA
FCBCSN+1,X
100E
60
4353
4354
,
RTS
100F
45
.INCLUDE #E:
100F
50
.INCLUDE #D:ATFMS4.SRC
RE*.D DATA SECTOR
.PAGE "READ DATA SECTOR"
RDNXTS - READ NEXT SECTOR
10eiF 5000
5001
5002
5003 ;
5004 RDNXTS
10flF BD8513 5005 LDA FCBFLG.X .-IF NOT UP0 MODE
1012 F003 5006 BEQ RDNSO ;BR
87
ATARI DOS 2.0S
1014
4C940F
5007
JMP
WRTNXS
.-ELSE WRITE FIRST
1017
5008
RDNSO
=
*
1017
BD8B13
5009
LDA
FCBLSN,X
;IF LSN NOT
101A
1D8C13
5010
ORA
FCBLSN+1,X
,- ZERO
101D
D002
5011
BNE
RDNSl
;BR
101F
38
5012
SEC
;ELSE EOF
1020
60
5013
RTS
1021
200210
5014
RDNSl
JSR
MVLSN
rMOVE LINK TO CURRENT
1024
18
5015
CLC
;READ
1025
20F90F
5016
JSR
RWCSIO
; CURRENT SECTOR
1028
3035
5017
5018
BMI
RDIOER
,-BR IF OK READ
5019
; ELSE
GOTO
I/O ERROR
5020
102A
ACF812
5021
LDY
DRVMDL
102D
B147
5022
LDA
(ZSBA) ,Y
,-TEST FOR SAME
102F
29FC
5023
AND
*$FC
rFILE NO
1031
DD8113
5024
CMP
FCBFNO.X
1034
D02C
5025
5026
BNE
RDFNMM
;IF NOT THEN ERROR
1036
B147
5027
LDA
(ZSBA) ,Y
;MOVE LINK SECTOR
1038
2903
5028
AND
#$03
103A
9D8C13
5029
STA
FCBLSN+1,X
103D
C8
5030
I NY
103E
B147
5031
LDA
(ZSBA),Y
1040
9D8B13
5032
5033
!
STA
FCBLSN,X
1043
C8
5034
I NY
;INC TO LEN BYTE
1044
B147
5035
LDA
(ZSBA) ,Y
;GET LEN BYTE
1046
48
5036
PHA
;SAVE IT
1047
BD8413
5037
LDA
FCBSLT.X
;GET SECTOR LEN TYPE
104A
D008
5038
5039
,
BNE
RDNS3
;BR IF NEW TYPE
104C
68
5040
PLA
rGET LEN
104D
3002
5041
BMI
RDNS2
;BR IF OLD SHORT SECTOR
104F
A97D
5042
LDA
#125
;ELSE SET FULL SECTOR
1051
297F
5043
RDNS2
AND
#S7F
jTURN OFF MSB
1053
48
5044
5045
,
PHA
; BALANCE STACK
1054
68
5046
RONS 3
PLA
1055
9D8613
5047
5048
STA
FCBMLN.X
;SET MAX LEN
1058
A900
5049
LDA
#0
;SET CUR DATA LEN =
105A
9D8713
5050
STA
FCBDLN.X
READ DATA SECTOR
105D
18
5051
CLC
105E
60
5052
RTS
105F
20E512
5053
RDIOER
JSR
ERRIO
;I/0 ERROR
1062
5054
RDFNMM
=
*
jFILE mjMBER MISMATCH
1062
BD4203
5055
LDA
ICCOM.X
1065
C921
5056
CMP
#$21
rWAS THIS DELETE
1067
F003
5057
BEQ
RDDELE
;BR IF DELETE
1069
20C712
5058
JSR
ERFNMM
;BR NOT DELETE
106C
38
5059
RDDELE
SEC
; INDICATE EOF TO DELETE
106D
60
5060
5061
,
RTS
READ/WRITE DIR
106E
106E 18
5062
5063
5064
5065
5066 RDDIR CLC
.PAGE "READ/WRITE DIR"
RDDIR/WRDIR READ/WRITE DIRECTORY
;SET READ
ATARI DOS 2.0S
i0e.F
9001
5067
5068
,
BCC
DIRIO
1071
38
5069
5070
WRTDIR
SEC
SET WRITE
1072
08
5071
DIRIO
PHP
SAVE READ WRITE
107 3
A914
5072
LDA
#FILDIR/256 rMOVE BUF ADDR
1075
8D0503
5073
STA
DCBBUF+1 ,
TO DCB
1078
A901
5074
LDA
#FILDIRJ.255
107A
8D0403
5075
5076
.
STA
dcb6uf
107D
18
5077
CLC
10-E
AD0613
5078
LDA
CD IRS
CDIRS+
10fil
6969
5079
ADC
#S69
((40*18)/2)+l
10f!3
A8
5080
TAY
INTO A,Y
10EI4
A901
5081
LDA
#1
IS DIR SECTOR NUMBER
10EI6
6900
5082
5083
.
ADC
*0
10(18
4CAB10
5084
5085
;
JMP
DSYSIO
GO DO SYSTEM I/O
READ/WRITE
VTOC
10HB
5086
.PAGE "READ/WRI
rE VTOC"
5087
.
5088
; RDVTOC/WRCTOC - READ/WRITE VTOC
5089
;
5090
RDVTOC
108B
A005
5091
LDY
♦DVDWRQ
•IF WRITE REQD
108D
B145
5092
LDA
(ZDRVA),Y
10«F
F001
5093
BEQ
RDVGO
1091
60
5094
RTS
10<»2
18
5095
RDVGO
CLC
;SET READ
1093
9007
5096
5097
,
BCC
VTIO
5098
WRTVTOC
1095
A005
5099
WRVTOC
LDY
♦ DVDWRQ
■TURN OFF
1097
A900
5100
LDA
#0
•WRITE READ
1099
9145
5101
STA
(ZDRVA),Y
109B
38
5102
5103
5104
;
SEC
109C
08
5105
VTIO
PHP
•SAVE R/W
109D
A546
5106
LDA
ZDRVA+1
■MOVE BUF ADDR
10?IF
8D0503
5107
STA
DCBBUF+1
•TO DCB
10;i2
A545
5108
LDA
ZDRVA
10;i4
8D0403
5109
5110
;
STA
DCBBUF
10^1 7
A068
5111
LDY
#S68
•READ SECTOR
10;i9
A901
5112
5113
5114
DSYSIO
LDA
#1
• (40*18)/2
i0;iB
28
5115
5116
DSYSIA
PLP
i0;,c
AEFE12
5117
LDX
DRVTYP
•LOAD DRIVE TYPE
i0;iF
206C07
5118
JSR
BSIO
■GO DO I/O
10112
3001
5119
BMI
DSIOER
•BR IF ERROR
10E14
60
5120
5121
5122
;
RTS
RETURN
10E15
C983
5123
DSIOER
CMP
#DCBDER
WAS IT DATA ERROR
10BI7
F003
5124
BEQ
DEAD
BR IF WAS
10E19
4CE512
5125
5126
.
JMP
ERRIO
ELSE USER PROBLEM
10E1C
4CC912
5127
5128
5129
5130
DEAD
;
; OPEN
JMP
VTOC
ERRSYS
FATAL ERROR
89
ATARI DOS 2.0S
5131 OPVTOC
10B:F 208B10 5132
10C2 4C9510 5133
5134
5135
5136
JSR
JMP
RDVTOC
WRTVTOC
;READ IT
;THEN WRITE IT
INSURES NOT PROTECTED
PREK SECTOR
10C!>
10C!>
10C»
10CH
10C1)
10C1'
10D:.
10D4
10D-'
10D()
10D9
BD8913
1D8A13
F038
A900
A003
5E8A13
7E8913
eA
88
D0F6
10DEI A005
10DI> eA
10Di; 88
10Dr D0FC
10E]. A8
10e;! A900
10E4 38
10E!; GA
10E(; 88
10EV 10FC
10E9 48
10E?. BD8913
10EII 690A
10EI' A8
10Fei 68
10F] 1145
10f;: 9145
10F5
10F7
10FSI
10F/.
10FC:
10FI
10FF
1101
1103
110!
110!
A003
B145
18
6901
9145
C8
B145
6900
9145
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
.PAGE "FREE SECTOR"
;
; FRESECT - FREE CURRENT SECTOR
FRESECT
FSl
FS2
FS3
LDA
FCBCSN.X
ORA
FCBCSN+1,X
BEQ
FSRTS
LDA
*0
LDY
#3
LSR
FCBCSN+1,X
ROR
FCBCSN.X
ROR
A
DEY
BNE
FSl
LDY
#5
ROR
A
DEY
BNE
FS2
TAY
LDA
#0
SEC
ROR
A
DEY
BPL
FS3
PHA
LDA
FCBCSN.X 1
ADC
fDVDSMP i
TAY
PLA
ORA
(ZDRVA),Y ■
STA
(ZDRVA).Y ;
LDY
#DVDNSA :
LDA
(ZDRVA).Y
CLC
ADC
#1
STA
(ZDRVA) .Y
INY
LDA
(ZDRVA),Y
ADC
#0
STA
( ZDRVA ) , Y
; DIVIDE SECTOR #
;BY 3 TO GET BYTE NO
rWITH REM IN ACU
TO FOR BYT BIT NO
■BIT NO (0-7) INTO Y
SHIFT IN A BIT
TO PROPER LOCATION
rSAVE MASK
GET BYTE NO
ADD OFFSET TO SMAP
■RESULT IS VTOC INDEX
GET BIT MASK
OF BIT TO BIT MAP
AND SET RESULTS
INC NO OF SECTORS AVAIL
FSRTS
GET SECTOR
11106
.PAGE "GET SECTOR"
5186
5187 ;
5188 ; GET SECTOR - GET A FREE SECTOR FOR
5189 ; USE IN FCB AT X REG. THE SECTOR
5190 jNUMBER IS PLACED IN FCBLSN
90
ATARI DOS 2.0S
net Aei09
110fl C8
110?i C064
110B B054
110D B145
110F F0F7
1111
1114
lli;i
llKi
lllH
lllA
iiic;
mi:
lllF
112:.
ii2;t
8C0C13
48
38
A003
B145
E901
9145
C8
B145
E900
9145
1121; C8
112r) A9FF
1120 9145
112A 68
112H A0FF
1121) C8
1121! 0A
1121' 90FC
1131 8C0D13
1134 4A
88
10FC
11313 AC0C13
11313 9145
11315
11315
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
THE SEARCH FOR A FREE SECTOR STARTS
AT THE DVDSMP BYTE. SECTORS ARE
NUMBERED SEQUENTIALLY FROM ZERO TO
MAXSM WITH THE LEFT BIT OF THE DVDSMP
BEING WITH ZERO.
GETSECTOR
LDY
GSl
GS3
#DVDSMP-1 ;SET Y TO START MAP-1
I NY ;INC SMAP INDEX
CPY ♦90+DVDSMP ;AT END OF MAP?
BCS GSERR ;BR IF AT END
LDA (ZDRVA),Y ; GET A MAP BYTE
BEQ GSl ;BR NO FREE SECTOR IN BYTE
;SAVE MAP INDEX
;DEC NO OF SECTORS AVAIL
STY
TEMPI
PHA
SEC
LDY
#DVDNSA
LDA
(ZDRVA),
,Y
SBC
#1
STA
(ZDRVA) ,
,Y
INY
LDA
( ZDRVA ) ,
,Y
SBC
#0
STA
(ZDRVA) ,
,Y
INY
LDA
#$FF
STA
(ZDRVA),
,Y
PLA
LDY
#$FF
INY
ASL
A
BCC
GS2
STY
TEMP 2
LSR
A
DEY
BPL
GS3
LDY
TEMPI
;SET READ REQD
;SET BIT COUNTER =-1
; SHIFT MAP BYTE
; UNTIL A FREE SECTOR
; FOUND
;SAVE BIT NUMBER
;AND SHIFT BYTE
; BACKS TO ITS ORIGINAL
; POSITION AND PUT IT
rBACK INTO THE MAP
STA ( ZDRVA ),Y
GET SECTOR
113D 38
1131: AD0C13
1141. E90A
1143 A000
114!i 8C0C13
1148 0A
1149 2E0C13
114(: C8
1141) C003
114F 90F7
115:. 18
1152 6D0D13
115,'j 9D8B13
1158 AD0C13
115B 6900
5237
5238
5239
5240 ,-
5241
5242
5243 ;
5244 GS4
5245
5246
5247
5248
5249 r
5250
5251
5252
5253
5254
SEC
LDA TEMPI
SBC #DVDSMP
LDY #0
STY TEMPI
A
TEMPI
ASL
ROL
INY
CPY #3
BCC GS4
CLC
ADC TEMP2
STA FCBLSN,
LDA TEMPI
ADC #0
r SECTOR NAP BYTE
;=DISPL-DVDSMP
; CLEAR SECT NO HI
rMULT REL SECTOR MAP
,-ADD BIT NO TO
; SECTOR #
;AND PUT INTO
; FCBLSN
91
ATARI DOS 2.0S
11;;d 9D8C13 5255
5256 ;
1160 60 5257
5258 ;
1161 4CCB12 5259 GSERR JMP ERRNSA
5260 ;
STA FCBLSN+1 , X
RTS
;N0 SECTOR AVAIL
SETUP ROUTINE
1164
1164 A99F
1166 8549
1168 8E0113
116B BA
11 6C E8
Hi5D E8
116E 8E0013
1171 AE0113
1174 A421
1176 8C0103
1179 88
117A B92913
117D 8545
117F B93113
1182 8546
1184 B91113
1187 F052
1189 8DFE12
118C A8
118D B9F812
11 '90 8DF812
ll'>3 B9FB12
1196 8DFB12
1199 BC8813
119C 88
119D 1031
119F A000
llAl B91913
11A4 F008
11A6 C8
11A7 C010
11A9 90F6
llAB 4CCD12
llAE ADFE12
llBl 4A
11B2 B010
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
.PAGE "SETUP ROUTINE"
SETUP - A ROUTINE USED FOR ALL COMMANDS
TO SET UP FMS CONTROLL CELLS
TO ACCESS A PARTICULAR FILE.
LDA #$9F
STA ERRNO
STX CURFCB
TSX
INX
I NX
STX ENTSTK
LDX
LDY
STY
DEY
LDA
STA
LDA
STA
LDA
BEQ
STA
GSBl
GSB2
GSB3
GSB4
LDY
LDA
BEG
INY
CPY
BCC
CURFCB
ICDNOZ
DCBDRV
DBUFAL.Y
ZDRVA
DBUFAH,Y
ZDRVA+1
DRVTBL.Y
DERRl
DRVTYP
TAY
LDA DRVMDL.Y
STA DRVMDL
LDA DRVLBT.Y
STA DRVLBT
LDY FCBBUF.X
DEY
BPL SSBA
#0
SECTBL.Y
GSB4
#16
GSBl
JMP ERRNSB
LDA DRVTYP
LSR A
BCS GSB5
;INIT ERROR CODE
rTO ZERO
rSAVE FCB
;GET CURRENT FCB
;MOVE DRIVE NO
rTO DCB
;DEC FOR ACCESS TO TABLES
;MOVE WRITE BUFFER
;ADD TO ZERO PAGE PTR
;GET DRIVE TYPE
;BR IF NOT EXISTS
rSAVE TYPE
jMOVE MAX DATA LEN
;AND LAST SECTOR BYTE
;DISPL TO LAST OF
; TABLES
;GET SECTOR BUF *
;DEC TO ACCESS TBL
;BR IF ONE IS ALLOCATED
;IF NON ALLOCATED
;TRY TO FIND ONE
;BR ONE FOUND
;DEC TRY COUNT
;BR MORE TO TRY
;N0 SECTOR BUFFERS AVAIL
; FOUND ONE IF 256 BYTES
.•DRIVE NEEDED TO CONT
;BR NOT 256 BYTES
SETUP ROUTINE
11:34 C8
5312
INY
1135 C010
5313
CPY
#16
1137 B0F2
5314
BCS
GSB3
1139 B91913
5315
LDA
SECTBL.Y
;ELSE TRY NEXT CONTIG
;TEST END OF BUFFERS
:AND BR IF NO MORE
;ELSE SEE IF ITS THREE
92
ATARI DOS 2.0S
IIBC D0E8
IIBEI 88
IIBF A980
llCl 991A13
11C4 A980
llC«i 991913
11C9 98
IICA 9D8813
IICI) FE8813
IIDH B93913
1103 8547
llDIi B94913
11D8 8548
IIDA 60
11D13 4CCF12
5316
5317
5318 ;
5319
5320
5321 ;
5322 GSB5
5323
5324
5325
5326
5327 ;
5328 SSBA
5329
5330
5331
5332 ;
5333 ;
5334
5335 7
5336 DERRl
BNE GSB2
DEY
;BR NOT FREE
LDA #S80 ; ALLOCATE SECOND OF 2
STA SECTBL+l,y
LDA #$80 ; ALLOCATE FIRST OR ONLY
STA SECTBL.Y
TYA
STA FCBBUF,X ;POT BUF NO INTO FCB
INC FCBBUF.X ;INC BUF NO SO NOT ZERO
LDA SABUFL.y ;MOVE BUFFER ADDR
STA ZSBA ;T0 ZERO PAGE PTR
LDA SABUFH.Y
STA ZSBA+1
RTS
JMP ERRDNO ;BAD DRIVE NO
SETUP ROUTINE
11D15
5337
.PAGE
5338
;
5339
; FREE
SECTOR BUFFERS
5340
;
IIDE
5341
FRESBUF =
*
IIDE
BC8813
5342
LDY
FCBBUF.X
■GET BUF NO
llEl
F013
5343
BEO
FSBR
•BR IF NONE
11E3
88
5344
DEY
;DEC FOR TBL ACCESS
11E4
A900
5345
LDA
#0
•FREE
11E6
9D8813
5346
STA
FCBBUF , X
;IN FCB
11E9
991913
5347
STA
SECTBL.Y
;AND TABLE
llEC
ADFE12
5348
LDA
DRVTYP
;IF 128 BYTES
llEF
4A
5349
LSR
A
; DRIVE
11F0
B004
5350
BCS
FSBR
;FREE ONLY ONE
11F2
4A
5351
LSR
A
;ELSE
11F3
991A13
5352
STA
SECTBL+1,Y
;FREE 2
11F6
60
5353
5354
FSBR
;
RTS
DATA SECTOR I/O
11F7
5355
.PAGE "DATA SI
:cn
^OR I/O"
5356
5357
; DSIO
- DATA SECTOR
I/O
5358
5359
DSIO
11F7
48
5360
PHA
SAVE ACU DATA
11F8
A547
5361
LDA
ZSBA
WRITE SECTOR BUF
UFA
8D0403
5362
STA
DCBBUF
ADR MOVED TO
IIFD
A548
5363
LDA
ZSBA+1
DCB
IIFF
8D0503
5364
STA
DCBBUF+1
1202
68
5365
5366
.
PLA
r RESTORE ACU
1263
AEFE12
5367
LDX
DRVTYP
1286
206C07
5368
JSR
BSIO
;D0 THE l/O
1229
60
5369
5370
;
RTS
WRITE DOS
120A
5371
.PAGE "WRITE
DOS"
5372
;
93
ATARI DOS 2.0S
5373
; WRTDOS -
WRITE DOS
TO DISK
5374
;
5375
WRTDOS
120A
BC8913
5376
LDY
FCBCSN.X
;MOVE START ADDR
120D
BD8A13
5377
LDA
FCBCSN+1 ,
,X
1210
205312
5378
JSR
SETDSO
rWRITE SECTOR
1213
206712
5379
JSR
WD0
; WRITE DOS
1216
4CF012
5380
5381
5382
DELDOS
JMP
GREAT
1219
A900
5383
5384
DDl
LDA
#0
;SET FILE NOT EXISTS
121B
8D0E07
5385
5386
5387
WRTSCO
STA
DFSFLG
121E
A907
5388
LDA
#FMSORG/256 ;MOVE FMS START
1220
8D0503
5389
STA
DCBBUF+1
jADDR TO DCB
1223
A900
5390
LDA
#FMSORGS.255
1225
8D0403
5391
5392
,
STA
DCBBUF
1228
A900
5393
LDA
*0
; CLEAR SECTOR NO TO
122ft
8D0A03
5394
STA
DCBSEC
122D
8D0B03
5395
5396
;
STA
DCBSEC+1
1230
EE0A03
5397
WRNBS
INC
DCBSEC
;INC SECTOR NO
1233
A201
5398
LDX
#1
;GET DRIVE TYPE
1235
38
5399
SEC
1235
207207
5400
5401
5402
;
JSR
BSIOR
;D0 THE WRITE
1239
18
5403
CLC
123A
AD0403
5404
LDA
DCBBUF
;INC SECT ADDR
123:d
6980
5405
ADC
#128
123?
8D0403
5406
STA
DCBBUF
1242
AD0503
5407
LDA
DCBBUF+1
1245
6900
5408
ADC
♦
1247
8D0503
5409
5410
.
STA
DCBBUF+1
124A
AD0A03
5411
LDA
DCBSEC
;TEST FOR WRITE
1243
CD0107
5412
CMP
BRCNT
;0F ALL BOOT SECTORS
1253
D0DE
5413
5414
.
BNE
WRNBS
;BR NOT ALL
1252
60
5415
5416
,
RTS
1253
8C0F07
5417
SETDSO
STY
DELINK
;SET LINK START
125i5
8D1007
5418
STA
DFLINK+1
125'J
ADFE12
5419
LDA
DRVTYP
125(:
8D0E07
5420
STA
DFSFLG
125P
ACF812
5421
LDY
DRVMDL
WRITE DOS
1262 8C1107 5422
1265 D0B4 5423
5424
STY BLDISP
BNE DDl
;G0 WRITE SECTOR
WRITE DOS
1267
5425
.PAGE
II
1267 AD1207
5426
WD0
LDA
DFLADR
;MOVE PILE START ADDR
126A 8543
5427
STA
ZBUFP
;TO ZBUFP
126C AD1307
5428
LDA
DFLADR+1
126F 8544
5429
5430
,
STA
ZBUFP+1
1271 A000
5431
WDl
LDY
#0
;MOVE 125
1273 B143
5432
WD 2
LDA
( ZBUFP ),Y
.•BYTES OF DOS
94
ATARI DOS 2.0S
12-'5
9147
5433
STA
(ZSBA),Y
1277
C8
5434
INY
1278
CCF812
5435
cpy
DRVMDL
127B
90F6
5436
BCC
WD 2
127D
98
5437
TYA
127E
9D8713
5438
5439
,
STA
FCBDLN.X
12131
205707
5440
JSR
INCBA
12:34
CD0D07
5441
CMP
SASA+1
1237
900B
5442
BCC
WD 3
12:39
D00F
5443
BNE
WD4
12:3B
A543
5444
LDA
ZBUFP
12:3D
CD0C07
5445
CMP
SASA
1230
9002
5446
BCC
WD 3
1292
D006
5447
5448
,
BNE
WD4
1294
20940F
5449
WD 3
JSR
WRTNXS
1297
4C7112
5450
5451
.
JMP
WDl
129A
60
5452
WD4
RTS
5453
; AND
RETURN
5454
r
;T0 SECTOR BUFFER
;SET DATA LEN
INC ZBUFP BY 125
IF NOT END OR
PAST END OF DOS
THEN WRTNXS
ELSE
DONE
rWRITE NEXT SECTOR
; RETURN, CLOSE WILL WRITE
FINAL SECTOR
TEST DOS FILE NAME
129B
129B A00B
129D B95813
12A0 D9A812
12A3 D003
12A5 88
12A6 D0F5
12A8 60
12A9 44
12AA 4F
12AB 53
12 AC 20
1::AD 20
12AE 20
1:;AF 20
i:!B0 20
i:iBi 53
i;:b2 59
i;!B3 53
12B4 20
5455
5456 ;
5457 ; TSTDC
5458 ;
5459 TSTDOS
5460
5461 TDFl
5462
5463
5464
5465
5466 TDFR
5467 ;
5468 DFN
.PAGE "TEST DOS FILE NAME"
TEST FOR DOS SYS FILE NAME;
LDY
LDA
CMP
BNE
DEY
BNE
RTS
#11
FNAME-
DFN-1,
TDFR
TDFl
.BYTE "DOS
;LOOK AT 12 CHARS
1,Y rTEST DECODE FILENAME CHAR
Y ;WITH DOS FILENAME CHAR
rBR NOT MATCH
rBR IF MORE, ELSE RTN EQ
SYS "
5469
5470
; ERROR ROUTINES
5471
!B5
E649
5472
ERDBAD
INC
ERRNO
!B7
E649
5473
ERAPO
INC
ERRNO
!B9
E649
5474
ERRPOT
INC
ERRNO
IBB
E649
5475
ERFNF
INC
ERRNO
iBD
E649
5476
ERDFULL INC
ERRNO
IBF
E649
5477
ERDVDC
INC
ERRNO
!C1
E649
5478
ERFLOCK INC
ERRNO
!C3
E649
5479
ERRPDL
INC
ERRNO
!C5
E649
5480
ERRFN
INC
ERRNO
!C7
E649
5481
ERFNMM
INC
ERRNO
!C9
E649
5482
ERRSYS
INC
ERRNO
;BAD SECTOR AT FORMAT TIME
; ATTEMPT APPEND TO OLD TYPE
FILE
; POINT INVALID
;FILE NOT FOUND
; DIRECTORY FULL
; DEVICE COMMAND INVALID
;FILE LOCKED
.•POINT DATA LENGTH
;FILE NAME ERROR
;FILE NUMBER MISMATCH
r FATAL SYS DATA l/O ERROR
95
ATARI DOS 2.0S
12CB
E649
5483
ERRNSA
INC
ERRNO
i2cn
E649
5484
ERRNSB
INC
ERRNO
12CF
E649
5485
5486
ERRDNO
INC
ERRNO
12D1
A549
5487
LDA
ERRNO
12D3
AE0113
5488
RETURN
LDX
CURFCB
12D6
9D4303
5489
STA
ICSTA.X
12D9
AE0013
5490
LDX
ENTSTK
12DC
9A
5491
TXS
12DD
AE0113
5492
LDX
CURFCB
12E0
A8
5493
TAY
12E1
AD0813
5494
LDA
SVDBYT
;N0 SECTOR AVAIL
;N0 SECTOR BUFFERS AVAIL
; DRIVE NO ERROR
;GET ERROR NUMBER
;GET CUR FCB NO
;PUT IN FCB
;GET ENTRY STACK PTR
;AND RESTORE
;GET SAVED DATA BYTE
TEST DOS FILE NAME
12E4
60
5495
5496
.
RTS
12E5
AD0303
5497
ERRIO
LDA
DCBSTA
;GET I/O ERROR CODE
12E8
30E9
5498
5499
,
BMI
RETURN
12EA
AE0113
5500
FGREAT
LDX
CURFCB
12ED
20DE11
5501
JSR
FRESBUF
rFREE SECTOR BUFFER
12F0
A901
5502
GREAT
LDA
#01
;SET ALL OK
12F2
D0DF
5503
BNE
RETURN
12F4
A988
5504
ERREOF
LDA
#588
rSET EOF CODE
12F6
30DB
5505
5506
.
BMI
RETURN
MISC STORAGE
12F8
5507
.PAGE "MI
5508
5509
; MISC
NON
ZERO
5510
12Ffl
00
5511
DRVMDL
.BYTE
12F9
7D
5512
.BYTE 125
12FA
FD
5513
.BYTE 253
5514
;
12FI!
00
5515
DRVLBT
.BYTE
12FC
7F
5516
.BYTE 127
i2Fn
FF
5517
.BYTE 255
i2Fi:
5518
DRVTYP
*=
*+l
i2Fr
5519
RETRY
*=
*+l
130CI
5520
ENTSTK
*=
*+l
1301
5521
CURFCB
* —
*+l
130:;
5522
DHOLES
*—
*+l
130;:
5523
DHOLED
*=
*+l
130A
5524
DHFNUM
* —
*+l
1305
5525
CDIRD
*=
*+l
1306
5526
CDIRS
*=
*+l
1307
5527
SFNUM
*=
*+l
130EI
5528
SVDBYT
*=
*+l
1309'
5529
SVDl
*—
*+l
130A
5530
SVD2
*—
*+l
130E;
5531
5532
SVD3
EXTSW
*=
*+l
130C
5533
TEMPI
*—
*+l
13011
5534
TEMP2
*=
*+l
13011
5535
TEMP 3
*=
*+l
130F
5536
TEMP4
*=
*+l
i3iei
5537
5538
BURTYP
*ss
*+l
1311
5539
DRVTBL
It-
*+8
1319
5540
SECTBL
It—
*+16
1329
5541
DBUFAL
*—
*+8
1331
5542
DBUFAH
*=
*+8
MAX DATA LEN
128 BYTE SECTOR
256 BYTE SECTOR
rDISPL TO LAST SECTOR BYTE
,•128 BYTE SECTOR
;256 BYTE SECTOR
; DRIVE TYPE
;l/0 RETRY COUNTER
; ENTRY STACK LEVEL
.■CURRENT FCB ( lOCB ALSO)
;DIR HOLE SECTOR
;DIR HOLE DISPL
DIR HOLE FILE NO
;CURRENT DIR DISPL
r CURRENT DIR SECTOR
;FILE NUMBER
; SAVED OUTPUT DATA BYTE
rSAVE DATA BYTES
.•FOR WRITE BURST
; TEMPI
;TEMP2
;TEMP3
;TEMP4
; BURST I/O TYPE
DRIVE TABLE
VTOC BUFFER
PTR FOR DRIVE N
96
ATARI DOS 2.0S
1339
5543
SABUFL
*s
*+16
; SECTOR BUFFER
1349
5544
SABUFH
*s
*+16
jFOR SECTOR N
1359
5545
FNAME
*s
*+12
;FILE NAME
1365
5 546
5547
AFNAME
*—
*+12
jAUXILLARY FILE NAME
1371
5548
5549
MDRV
*=
*+l
jMAX DR NO
1372
5550
Z
=
*
;PUT ON SAME BOUNDRY AS
PRODUCTION
1372
5551
*s
$1381
;VERSION
F]:LE CONTROL BLOCKS
13181
5552
.PAGE "FILE CONTROL BLOCKS"
5553
•
5554
; FILE
CONTROL BLOCK
5555
; ONE FILE
CONTROL BLOCK IS USED FOR EACH
5556
; OPEN
FILE. THE RELATIVE FCB USED
5557
; RELATES
DIRECTLY TO THE lOCB *
5558
r THAT
OPENED THE FILE.
THUS THERE ARE
5559
; 8 FCBS.
THE FCB ARE
(CONVIENTLY)
5560
; THE SAME
SIZE AS lOCBS. EACH FCB
5561
; CONTAINS
ALL THE INFORMATION REQUIRED
5562
; TO CONTROL THE PROCESSING ON AN
5563
r OPEN
FILE
5564
;
5565
FCB
1381
5566
FCBFNO
*=
*+l ;
FILE # LEFT JUSTIFIED
1382
5567
FCBOTC
*=
*+l
OPEN TYPE CODE
1383
5568
*=
*+l ;
SPARE
1384
5569
FCBSLT
*—
*+i ;
FLAG FOR NEW SECTOR LEN 1
1385
5570
FCBFLG
*=
*+l
WORKING FLAG
1386
5571
FCBMLN
It-
*+l
MAX SECTOR DATA LEN
1387
5572
FCBDLN
It—
*+l
CUR SECTOR BUF DATA LEN
1388
5573
FCBBUF
*—
*+l
SECTOR BUF NO
1389
5574
FCBCSN
*=
*+2
CUR SECTOR #
138B
5575
FCBLSN
*—
*+2
LINK/ALLOCATE SECTOR #
138D
5576
5577
FCBSSN
FCBCRS
*—
*+2
CUR FILE RELATIVE SECTOR
138F
5578
FCBCNT
*=
*+2
SECTOR COUNT
0310
5579
5580
FCBLEN
-
*-FCB
FCB LEN
1391
5581
5582
* =
FCBLEN*7+*
; ALLOCATE 7 MORE FCBS
5583
r OPEN
CODE BITS
5584
; USED
IN
lOCB AUXl
5585
; - AND FCBOTC
5586
0004
5587
OPIN
=
$04
-INPUT
0008
5 588
OPOUT
=
$08
•OUTPUT
0002
5589
OPDIR
=
$02
jLIST DIRECTORY
0001
5590
5591
OPAPND
=
$01
; APPEND
0080
5592
FCBFAS
=
$80
; FCBFLG - ACQ SECTORS
0040
5593
FCBFSM
=
$40
; FCBFLG - SECTOR MODIFIED
FILE
DIRECTORY
1401
5594
.PAGE "FILE DIR
ECTORY"
5595
•
5596
,- DISK
FILE DIRECTORY
5597
; THE
FILE DIRECTORY
CCUPIES 8
5598
;CONSECTUIVE SECTORS S
TARTING AT THE
5599
,• CENTRAL
SECTOR+1 . E
ACH FILE DIRECTORY
5600
; SECTOR CONTAINS 8 EN
[TRIES . THERE
5601
; IS 1
ENTRY FOR EACH
NAMED FILE. THE
97
ATARI DOS 2.0S
0001
0003
0005
000D
0011?'
000(1
008 ei
004(1
0001
0020
000;
1401
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
THERE ARE A TOTAL OF 64 NAMED FILES
PER VOLUME
THE FILE NUMBER IS USED THROUGH THE
THE SYSTEM IS THE RELATIVE (TO ONE)
FILE DIRECTORY ENTRY NUMBER.
THE EQUATES BELOW ARE FOR A SINCE NAMED
FILE ENTRY
DFDFLl =
DFDCNT =
DFDSSN =
DFDPFN =
DFDXFN =
DFDELN =
1
3
5
13
16
;FLAG1 (1)
; SECTOR COUNTER (LOW)
; START SECTOR NO (2)
; PRIMARY FILE NAME (8)
rEXTENDED FILE NAME (4)
; ENTRY LENGTH
DFDFLl VALUE EQUATES
DFDEUU
DFDEDE
DFDINU
DFEXJUT
DFDLOC
DFDNLD
FILDIR *=
$80
$40
$01
$20
$02
*+256
; ENTRY UNUSED
r ENTRY DELETED
.•ENTRY IN USE
;FILE OPEN FOR OUTPUT
.•ENTRY LOCKED
;FILE HAS NEW TYPE SECTOR LEN
BYTE
r RESUME FILE DIR SPACE
VOLUME DIRECTORY
1501
0000
0001
0003
0005
000A
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
.PAGE "VOLUME DIRECTORY"
DISK VOLUME DIRECTORY
THE VOLUME DIRECTORY OCCUPIES THE CENTRAL
VOLUME SECTOR. THE VOLUME DIRECTORY
CONTAINS INFORMATION PERTAINING TO
THE ENTIRE DISKETTE VOLUME.
THE LABELS BELOW, MAP THE VOLUME
DIRECTORY SECTOR.
DVDTCD
; VOLUME DIRECTORY TYEP CODE )1)
USED TO DELINATE MAJOR (1)
FMS SYSTEM FORMAT CHANGES
DVDMSN =
DVDNSA =
DVDWRQ
DVDSMP
5
10
;MAX SECTOR NUMBER (1)
rNO SECTORS AVAIL
rWRITE REQUIRED
.•SECTOR MAP START
EACH BIT REPRESENTS A SECTOR
IF THE BIT IS ON THEN THE SECTOR
IS FREE AND AVAILABLE. IF THE
BIT IS OFF, THE SECTOR IS IN
USE OR BAD. THE MOST SIGNIFICANT
BIT OF THE FIRST BYTE IS SECTOR ZERO.
END OF FMS
1501
1501
1501
5658
5659 ;
5660 ENDFMS =
60 . END
PAGE "END OF FMS"
98
ATARI DOS 2.0S
EtID OF FMS
=0700
FMSORG
=0043
FMSZPG
=0340
lOCBORG
=0003
LMASK
=£1300
DCBORG
=E453
DHADR
=009B
EOL
=031A
DEVTAB
=CI020
ZICB
=02E7
LMADR
=1540
DUPINIT
=0102
STAR
=00DF
OSBTM
=0246
DSKTIM
=000F
TIMOUT
0340
lOCB
0340
ICHID
0341
ICDNO
0342
ICCOM
0343
ICSTA
0344
ICBAL
0345
ICBAH
0346
ICPUT
0348
ICBLL
0349
ICBLH
034A
ICAUXl
034B
ICAUX2
034C
ICAUX3
034D
ICAUX4
034E
ICAUX5
034F
ICAUX6
=0010
ICLEN
=0001
ICOIN
=0002
ICOOUT
=0003
ICIO
=0004
ICGBR
=0005
ICGTR
=0006
ICGBC
=0007
ICGTC
=0008
ICPBR
=£1009
ICPTR
=000A
ICPBC
=000B
ICPTC
=000C
ICCLOSE
=000D
ICSTAT
=000E
ICDDC
=000E
ICMAX
=000F
ICFREE
=£1001
ICSOK
=0002
ICSTR
=0003
ICSEOF
=0080
ICSBRK
=0081
ICSDNR
=0082
ICSNEP
=0083
ICSDER
=0084
ICSIVC
=0085
ICSNOP
=0086
ICSIVN
=0087
ICSWPC
=0021
ICDNOZ
=0028
ICBLLZ
=0029
ICBLHZ
=0024
ICBALZ
=0025
ICBAHZ
=0022
ICCOMZ
=0026
ICPUTZ
0300
DCB
0300
DCBSBI
0301
DCBDRV
0302
DCBCMD
0303
DCBSTA
0304
DCBBUF
0306
DCBTO
0308
DCBCNT
030A
DCBSEC
=0052
DCBCRS
=0050
DCBCWS
=005 3
DCBCST
=0021
DCBCFD
=0001
DCBSOK
=0081
DCBDNR
=0082
DCBCNR
=0083
DCBDER
=0084
DCBIVC
=£1087
DCBWPR
0043
ZBUFP
0045
ZDRVA
0047
ZSBA
0049
errno
0700
BFLG
0701
BRCNT
0702
BLDADR
0704
BINTADR
0706
BCONT
0714
XBCONT
0709
SABYTE
070A
DRVBYT
070B
SAFBFW
070C
SASA
=1501
ENDFMS
070E
DFSFLG
070F
DFLINK
0711
BLDISP
0712
DFLADR
07CB
DFMSDH
074F
BFAIL
072F
XBCl
=076C
BSIO
0753
BGOOD
0757
INCBA
0754
XBRTN
0772
BSIOR
077C
DSIOl
0786
DSI02
12FF
RETRY
079C
DSI03
07A2
DSI04
07C4
DSI05
07BE
STRTYP
1301
CURFCB
08AB
DFMOPN
0B15
DFMCLS
=0ABF
DFMGET
09CC
DFMPUT
0B01
DFMSTA
0BA7
DFMDDC
=07E0
DINIT
130C
TEMPI
07P2
DIA
130D
TEMP2
0807
DIHAVE
1311
DRVTBL
1329
DBUFAL
1331
DBUFAH
083D
DIDDEC
=0005
DVDWRQ
0823
DI256
0870
DINCBP
0845
DINXTS
084B
DISETS
1319
sectbl
08 5E
DISNI
1339
SABUFL
1349
SABUFH
=087E
CLRFCB
0882
CFCBX
1381
FCB
088A
ADIl
089B
ADI2
1164
SETUP
0E9E
FNDCODE
1382
FCBOTC
=0002
OPDIR
08BE
OPNl
0DAD
LISTDIR
0F21
SPDIR
=0004
OPIN
=08D8
DFOIN
=0008
OPOUT
=0911
DFOOUT
=08DD
DFOUPD
=0001
OPAPND
=fl8EC
DFOAPN
12BF
ERDVDC
08E9
OPNERl
=08E3
DFOUI
0CAC
TSTLOCK
09AE
DFRDSU
12F0
GREAT
12BB
ERFNF
1305
CDIRD
1401
FILDIR
=0000
DFDFLl
=0002
DFDNLD
090E
APOER
10BF
OPVTOC
].106
GETSECTOR
138D
FCBSSN
13aB
FCBLSN
=097C
DHF0X2
].2B7
ERAPO
=091D
DFOXl
0C53
XDEL0
=0948
OPNIA
1302
DHOLES
0992
0PNER2
1306
CDIRS
10eE
RDDIR
:.303
DHOLE D
1304
DHFNUM
1307
SFNUM
093E
OPNIB
=0005
DFDPFN
=0003
DFDSSN
=0040
DFDINU
=0001
DFDOUT
=0001
DFDCNT
0966
0PN2
1359
FNAME
=0970
0PN2A
1071
WRTDIR
=0995
SETFCB
0FE2
WRTN6
0982
0PN3
=0080
FCBFAS
1385
FCBFLG
129B
TSTDOS
=098F
DHF0X3
].20A
WRTDOS
12BD
ERDFULL
099A
OPNFl
1381
FCBFNO
1387
FCBDLN
138F
FCBCNT
1384
FCBSLT
=1017
RDNSO
1308
SVDBYT
1300
ENTSTK
09E5
FRMCIO
0A19
PUTER
1386
FCBMLN
0A06
PUTl
0F94
WRTNXS
0A1C
PEOF
OAIF
WTBUR
=0040
FCBFSM
12F4
ERREOF
0A4A
NOBURST
0A28
TBURST
0A26
RTBUR
1310
BURTYP
=0AAE
TBLEN
()A3E
NXTBUR
0A4C
WRBUR
100F
RDNXTS
0A7B
BBINC
=I)A9D
BUREOF
12F8
DRVMDL
1309
SVDl
130A
SVD2
:L30B
SVD3
1388
FCBBUF
11D0
SSBA
0AAC
BURST
:l2pe
DRVTYP
0AB9
TBL256
0ACC
GETl
0DB9
GDCHAR
UADF
GET 2
=0ADC
GEOF
=0AEA
EFLOOK
0AFE
GET3
:L2D3
RETURN
0B12
SFNF
0B6D
CLDONE
=0B75
CLUPDT
IJFAB
WRTLSEC
=0B80
RRDIR
0B50
CLOUT
0B3C
APPl
99
ATi\RI DOS 2.0S
0FB3
WRTN2
1095
WRTVTOC
12EA
FGREAT
0FF8
WRCSIO
0B9B
FNSHFT
0B9D
FNSHFl
0B9F
FNSHF2
0BD6
XFV
■0027
MAXDDC
0BD3
DVDCER
0BC5
DVDCVT
0BD9
XRENAME
0C32
XDELETE
0C7C
XLOCK
0C83
XONLOCK
0CBA
XPOINT
0D03
XNOTE
0D18
XFORMAT
0BE7
XRNl
0BF2
XRNl A
1219
DELDOS
0EB4
FNDCNX
0C0C
XRNIB
1253
SETDSO
0C11
XRN2
0C1B
XRN3
0F31
CSFDIR
0C79
DFNF
=0C3A
XDELX
0C45
XDELY
0C45
XDEL3
0C56
XDELl
=008 C!l
DFDEDE
=0C6C
XDEL2A
0C67
XDEL2
=0C72
XDEL4
10C5
FRESECT
=0020
DFDLOC
130F
TEMP4
0C88
XLCOM
0C93
XLCl
0CB7
TLF
12C1
ERFLOCK
0D00
PERRl
1389
FCBCSN
0CCF
XPl
0CED
XP2
=0CDC
XPl A
=0CF7
XPERR
0CFA
XP3
12C3
ERRPDL
12B9
ERRPOT
0D52
XF0
0D4F
XFERR
=0D3D
TSTFMT
0D4C
XFBAD
12B5
ERDBAD
0D55
XFl
=000A
DVDSMP
0D76
XF2
0D94
XF3
0D9F
XF4
0DE3
LDENTl
0DE9
LDCNT
0E11
LDDONE
0DD6
GDCRTN
0DD9
LDENT
0E21
FDENT
108B
RDVTOC
=0003
DVDNSA
0E57
CVDX
=000D
FSCML
0DFD
MVFSCM
0E14
FSCM
0E67
CVDY
0E35
LDl
0E3B
LD2
0E71
CVDIGIT
0E8D
STDIGIT
130E
TEMP3
0E76
CVDl
0EAA
FD0A
0F07
FNDERR
0EB3
FD0B
0EB8
FD0
130C
EXTSW
0EC3
FDl
0ED5
FD3
0ECR
FD2
0F0A
FDSCHAR
0F03
FDEND
0EE5
FD4
0EFD
FD6
0EF1
FD5
12C5
ERRFN
0F1B
FDSC2
0F15
FDSCl
=0010
DFDELN
0F4D
SFD2
0F48
SFDl
0F90
SDRTN
0F73
SPDSH
0F5E
SFD3
0F6A
SFD4
0FBA
SFDSHl
0FA8
WRTNl
0FA5
WRUl
0FC9
WRNERR
0FAE
WRTLSl
12FB
DRVLBT
0FDA
WRTN5
1002
MVLSN
0FF6
WRNRTS
0FF9
RWCSIO
11F7
DSIO
1021
RDNSl
105P
RDIOER
=1062
RDFNMM
1054
RDNS3
1051
RONS 2
12E5
ERRIO
106C
RDDELE
12C7
ERFNMM
1072
DIRIO
10AB
DSYSIO
1092
RDVGO
109C
VTIO
1095
WRVTOC
10AC
DSYSIA
10B5
DSIOER
10BC
DEAD
12C9
ERRSYS
=1105
FSRTS
10D1
FSl
10DD
FS2
10E5
FS3
1108
GSl
1161
GSERR
112D
GS2
1134
GS3
1148
GS4
12CB
ERRNSA
IIDB
DERRl
llAl
GSBl
llAE
GSB4
11A6
GSB2
llAB
GSB3
12CD
ERRNSB
11C4
GSB5
12CF
ERRDNO
=11DE
FRESBUF
11F6
FSBR
1267
WD0
121B
DDl
121E
WRTSCO
1230
WRNBS
1271
WDl
1273
WD 2
1294
WD 3
129A
WP4
129D
TDFl
12A9
DFN
12A8
TDFR
1365
AFNAME
1371
MDRV
=1372
Z
138F
FCBCRS
=0010
FCBLEN
=000D
DFDXFN
=0000
DFDEUU
=0000
DVDTCD
=0001
DVDMSN
100
v^
^
Appendix A
AN
INTERMEDIATE
USER'S GUIDE
TO THIS BOOK
If you are familiar with machine language, commented source code,
and hexadecimal numbers, you probably won't need to read this
appendix. On the other hand, if you don't know or are new to machine
language - perhaps some of the information here will help.
A knowledge of machine language is important to grasping the
sense of the DOS since it is written in machine language. However,
we will briefly cover some of the fundamentals, as they relate to the
book, in the hope that this might be a starting point. One of the
functions of this book is to reveal the inner workings of Atari DOS. A
benerit of knowing how it works is that you are able to change it to
suit yourself, to customize it.
First we'll examine the meaning of the various fields of information
whicli are in the source code (page 59 on). Then, after a brief look at
how ro deal with hexadecimal numbers, we can make a modification
to D(DS step-by-step to show how it's done.
The book is divided into two sections: roughly the first half is a
series of descriptions of the major subroutines of the disk operating
system. The latter half is a commented source code of the DOS. In order
to better understand what you can accomplish with all this information,
we can set up a problem and solve it using the book.
Whoit's "Commented Source Code"?
We'll change the DOS so that we could type in a disk command using
lowercase letters. Unfortunately, the D: must be in uppercase, the
program which makes this decision is in ROM and we can't get at it
and change it. The rest of the command can be in lowercase, though,
after we make our change to the DOS in RAM. After fixing it, any
routine that uses the disk will accept lowercase as in D: open.
102
APPENDIX A
Before getting into the details of the modification there is some
important preliminary information. What, for example, is "commented
source code?"
Machine language differs in several respects from BASIC. When
you write a program in BASIC, you never see how it looks to the
computer. Instead you see something like this:
10 FORI = lTO100
20 NEXT 1
This delay loop just creates a brief pause in a program. If you
RUN the above, the computer handles the problem of translating the
BASIC words into machine language. Anything the computer does
must be translated into machine language (ML). Translating (or
interpreting) a BASIC program takes place during the RUN of the
program - that's why BASIC is so slow compared to ML.
By contrast, ML is translated before it is RUN. Programming ML
is done in two stages: 1. writing the source code and then 2. assembling
it into object code. The computer does most of the drudgery of this
because most ML is written by using a program called an assembler
which handles many of the details. Some assemblers are so complex
ttiat using them can seem almost like programming in BASIC.
Here is how you might program the above example delay loop
when using an assembler:
1 000 LDY #64 ; SET COUNTER TO 1 00
1001 LOOP DEY
1002 BNE LOOP
Probably the most peculiar thing about this, to the beginner, is
how 64 stands for 100 (it's hex, we'll get to it in a minute). The line
nambers could be BASIC, but the instructions are 6502 mnemonics
(memory aids). LDY means to load the Y register with 100 (decimal).
The next line is named (labelled) "loop" because assemblers don't say
CiOTO 1001. Instead, they use convenient names. In any event, the
Y register is decremented by DEY, it's lowered by one. So each time
the program cycles through the LOOP address, it will lower the counter
one. Finally, the instruction at 1002 says. Branch if Not Equal (to
zero). In other words, GOTO LOOP if Y hasn't yet counted down to
zero. When Y reaches zero, the program will continue on, following
whatever instruction is in line 1003.
After the above program is written, though, it still cannot be
BUN. There is the second step, the creation of object code
((Executable), the assembly process.
You tell the assembler to assemble this program. The result of
103
APIPENDIXA
that is an additional two "fields" (zones). Above, we have five fields:
line number, label, mnemonic (instruction), operand (the #64), and
a comment field which is the equivalent of BASIC REM statements.
There will soon be a total of seven fields.
After assembly, the two new fields are the addresses and the
object code (expressed as hex bytes). By the way, BASIC always
assigns its programs a starting address in memory, but, in ML, the
programmer must make this known to the assembler. It's not the
computer's decision. Assume the computer were told to assemble the
above example at address $2000 (this would be 8192, in decimal).
The dollar sign means that a number is a hex number. The labels,
mnemonics, and operands would be translated into object code and
put into the computer's memory. As you'll see in the second half of
this iDook, a printout of completed assembly looks like this:
200C AOOO 1000 LDY #64 ; SET COUNTER TO 100
2002 88 1001 LOOP DEY
2003 DOFF 1002 BNE LOOP
Hex
Before concluding this brief overview of some fundamentals of machine
language, we should explain how to read the numbers in the source
code listings.
100 DIM H$(23) ,N$(9) :OPEN#1,4,0,"K:"
130 GRAPHICS
140 PRINT "PLEASE CHOOSE:
150 PRINT "1 - Input HEX & get decimal back
n
160 PRINT "2 - Input DECIMAL to get hex bac
k."
170 PRINT:PRINT "==>"; :GET#1 ,K
180 IF K<49 OR K>50 THEN 170
190 PRINT CHR$(K):ON K-48 GOTO 300,400
300 H$="@ABCDEFGHI! ! ! ! ! ! IJKLMNO"
310 PRINT "HEX";:INPUT N$:N=0
320 FOR 1=1 TO LEN(N$)
330 N=N*16+ASC(H$(ASC(N$(I))-47))-64:NEXT I
350 PRINT "$";N$;"=";N:PRINT:PRINT:GOTO 140
400 H$="0123456789ABCDEF"
410 PRINT "DECIMAL"; : INPUT N:M=4096
4 20 PRINT N;"=$";
104
APPENDIX A
430 FOR 1=1 TO 4:J=INT{N/M)
440 PRINT H$(J+1,J+1) ; :N=N-M*J:M=M/16
450 NEXT I:PRINT:PRINT:GOTO 140
This program will turn a decimal number into hex or vice versa.
Hexadecimal is a base 16 number system, where decimal is base ten.
This means that you count from zero to fifteen before going to the
n(!xt column. For example, you count up zero one two. . .until you
reach nine in decimal. Then you go to the next column and have a
one-zero (10) to show that there is one in the "ten's column" and zero
ir the "one's column. "
In hex, what was a "ten's column" becomes a "sixteen's column."
In other words, the symbol "10" means that there is one sixteen and
zero "ones." So, the decimal number 17 would be written in hex, as
$11 (one sixteen plus one one). The decimal number 15 would, in
hex, be $0F. After nine, we run out of digits, so the first few letters of
the alphabet are used: A= 10, B= 11, C= 12, D= 13, E= 14, and
F=15.
This explains how to "read" hex numbers if you don't want the
pirogram above to do it for you. The number $64 is decimal 100 because
there are six 16's and four one's. 6 X 16 4- 4 = 100.
Addresses can be larger than two digits, up to a maximum of
four. You might see an address such as $1 1F7 in the listings. The third
column is the 256's and the fourth column is the 4096's. So to find
out what this address is in decimal, you can multiply 7X1, 15X16,
1 X 256, and 1 X 4096. And add them all together.
A quicker way is to find out the first two, (15x16 + 7 = 247) and
tlien multiply the second two by 256. It comes out the same. The
second two would be $ 1 1 ( 1 7 in decimal) so 1 7 x 256 + 247 = 4599. It
might be easier to just use the BASIC program to make the translations
until hex becomes more familiar.
Making A Modification
Now that you have the entire source listing of EXDS 2. OS, you can
customize it to fit your needs.
You may have felt restricted by the limitations on file names. A
file name can consist of eleven characters: up to eight characters plus
an optional three-character extension. The first character must be
from A-Z; subsequent characters can be from A-Z or 0-9. That's it.
f >]o punctuation. No imbedded spaces. No lowercase.
By changing only two locations in the file name decode section
of DOS, many more characters are permitted. We will modify DOS to
105
APPENDIX A
accept any ASCII characters in a file name except character graphics
and inverse video. Additionally, the filename can start with a number
(e.g. "D:3-D"). Unfortunately, there is no foolproof way to allow
imbe^dded spaces such as "D:TIME OUT".
The following fragment of code checks to see that a character of
the file name falls in the range of A-Z. If the character is less than
(cany clear) 65 [ASC("A")] or greater than or equal to (carry set) 91
[ASCC'Z") + 1], then the test fails. All we do is change the check for
"A" to a check for "!" (its number in the code is one greater than
"space"), and the check for "Z" + 1 to "z" + 1 (lowercase z).
Included in this range of 90 characters are the numbers (48-57)
and all punctuation. Since we start with 33, "space" is excluded. It is
possible to permit imbedded spaces, but the file would then be
inaccessible in certain situations where a space is used as a delimiter.
You i:an allow it at your discretion, or even permit the entire (almost)
AT/iSCII character set to be used by changing the limits to
and 155.
CMP #'A
BCC FD5
CMP #$5B
BCC FD6
We change this to:
CMP #'!
BCC FD5
CMP #$7B
BCC FD6
The changes can be made in BASIC with POKE 38 18, 33: POKE
3822, 123 or change hex locations $OEEA to $21 and $OEEE to $7B.
The section of code we're modifying is located between source line
numbers 4072 through 4193. Remember to rewrite the modified DOS
to disk with WRITE DOS FILES (Menu selection "H") if you want
your change to be permanent.
Other equally simple changes are also possible. You could change
the wild-card character ("*") to any other character by changing
location $0EC7 to the desired character. A more ambitious task
would be to increase the maximum file name length.
This brings up a final point - software compatibility. For example,
if you changed the wild card character to "@," you couldn't run any
previ.3us programs that assume "*" as the wild card character. Our
change is less dangerous - if you allow lowercase file names, the
unmodified DOS won't be able to access it, although it will look fine
on the directory. This change has not been exhaustively tested for
106
APPENDIX A
conflicts, so we can't guarantee its usage. Nevertheless, it seems quite
useful and shows that some customizing can be accomplished with a
few simple changes.
When experimenting, always keep a backup copy of your valuable
disks in case something should go awry.
100 REM CHANGE DOS PROGRAM
110 REM FOR DOS 2.0S ONLY
120 REM CHANGE LOW RANGE CHECK FROM
130 REM 65 TO 33. THIS ALLOWS
140 REM ANY CHARACTER (EXCEPT
150 REM GRAPHICS AND INVERSE VIDEO)
160 REM TO START A FILENAME, INSTEAD
170 REM OF ONLY A THROUGH Z.
180 REM 0EE9 C941 CMP #'A
190 REM 0EE9 C921 CMP #'!
200 POKE 3818,33
210 REM CHANGE HIGH RANGE TO EXTEND
220 REM UP TO ASCII "z"
230 REM (LOWERCASE Z)
240 REM 0EED C95B CMP #$5B
250 REM 0EED C97B CMP #$7B
260 REM POKE 3822,123
270 REM NO NEED TO CHANGE NUMERIC
280 REM CHECK SINCE IT IS NO
290 REM LONGER EXECUTED, THANKS
300 REM TO THE ABOVE CODE.
Siome Cautions
C^^are is necessary when making customizations. Only make the changes
to a copy of your EXDS - not the original "system master." (You
shouldn't be able to do this anyway, since the disk is "write-protected, "
but better safe than sorry. ) Remember that any files SAVEd with your
custom EXDS will probably not be compatible with the original,
unchanged DOS. Alternation of the DOS can have unpredictable
effects; we urge caution and cannot accept any liability for software or
hardware damage incurred through the use of this book.
Things To Looi( Out For
These modifications could make a customized DOS incompatible with
the original, unmodified DOS 2. OS:
1) File name changes (such as allowing lowercase, or increasing
107
APPENDIX A
the length)
2) Changes to DOS file stnicture (such as using a different
"linking" system)
3) Removing error-checks. These built-in traps insure disk
integrity and reliability. When you alter one, you could risk
muddling one or more files. For example, if you allow an automatic
"wild-card" feature, where an asterisk is assumed at the end of a
file, it could cause havoc when performing a SCRATCH,
RENAME, or UPDATE operation. Another example is removing
some of the qualifications for "burst- I/O." Remember that a lot
of thought went into each design consideration.
Keeping these suggestions in mind, here are some ideas for
modifications. You may need to type in and re-assemble (with your
insertions) the entire DOS when making certain modifications.
1 ) Adding a STATUS check before a disk access. Have you ever
noticed how long the drive will grind away when no disk is
inserted? You can query the disk for its status, and even add a
"Drive not ready" error message if the drive door is not closed or
a disk is not inserted. Check your DOS manual for details.
2) Adding Disk Utility commands. These would be additional
functions performed by the FMS, keyed to the "special command. "
Some of the tasks performed by the Disk Utility Package could be
a part of the DOS kemal, such as LOAD and SAVE binary files.
You could even implement new commands such as "relative file"
support, where you only give the DOS a "record number" to
randomly access a file. The file could be divided into records of
any length.
3) Allocate more sectors for the directory, thereby extending
the maximum amount of directory entries.
4) Add a disk name and/or disk I.D. number (serial number?) to
the disk (maybe on sector 720). It could even print out with the
directory.
5) Given the extra "unused" bytes in the file name, add a byte
for file type, such as program, data, object code, etc. , and have it
printed out with the directory, making it easy to identify files
without having to use the extension. This would be hard to
interface with software, however.
Remember that some of this is risky business. Keep backup disks
for any disk you are "experimenting" with. That way, you should lose
no important files.
The publishers and authors of this book disclaim any responsibility for errors or
problems caused by modification of Atari DOS 2. OS.
108
NOTES
109
NOTES
110
NOTES
111
NOTES
112
NOTES
113
NOTES
114
NOTES
115
NOTES
116
COMPUTE! Books
P.O. Box 5406 Greensboro, NC 27403
Ask your retailer for these COMPUTE! Books. If he or she
has sold out, order directly from COMPUTE!
For Fastest Service
Call Our TOLL FREE US Order Line
800-334-0868
In NC call 919-275-9809
Quantity Title Price Total
The Beginner's Guide To
Buying A Personal Computer $ 3.95
(Add $1.00 shipping and handling. Outside US add
S4.00 air mail: $2.00 surface mail.)
COMPUTEI's First Boole Of Atari $12.95
(Add $2.00 shipping and handling. Outside US add
$4.00 air mail; $2.00 surface mail.)
Inside Atari DOS $19.95
(Add S2.00 shipping and handling. Outside US add
$4,00 air mail; $2.00 surface mail.)
COMPUTERS First Book Of
PET/CBM $12.95
(Add $2.00 shipping and handling. Outside US add
S4.00 air mail; $2.00 surface moil.)
Programming ttie PET/CBM $24.95
[Add S3.00 shipping and handling. Outside US odd
$9,00 air moil; $3.00 surface moil.)
Every Kid's First Boole of
Robots and Computers $ 4.95
(Add $1.00 shipping and handling. Outside US odd
$4.00 air moil; $2.00 surface mail.)
COMPUTEI's Second Book Of
Atari $12.95
[Add S2.00 shipping and handling. Outside US odd
$4.00 air mail: $2.00 surface moil.)
COMPUTEI's First Book of VIC $12.95
(Add $2.00 shipping and handling. Outside US add
S4.00 oir mail; $2.00 surface mail.)
All orders must be prepaid (nnoney order, check, or charge). All
payments must be in US funds. NC residents add 4% sales tax.
□ Payment enclosed Please charge my: □ VISA □ MasterCard
□ American Express Acct No. Expires /
Name
Address
City State Zip
Country
Allow 4-5 weel<s for delivery
02 7
^
f you've enjoyed the articles in this book, you'll find the
some style and quality in every monthly issue of COMPUTE!
Magazine. Use this form to order your subscription to
COMPUTE!
For Fastest Service,
Call Our Toil-Free US Order Line
800-334-0868
In NO call 919-275-9809
COMPUTE!
P.O. Box 5406
Greensboro, NC 27403
My Computer Is:
DPET DApple DAtari DVICDOther D Don't yet have one...
D $20.00 One Year US Subscription
n $36.00 Two Year US Subscription
D $54.00 Three Year US Subscription
Subscription rotes outside the US:
D $25.00 Canada f=2
D $38.00 Europe/Air Delivery fi = 3
D $48.00 Middle East, North Africa, Central America/Air Mail fi = 5
n $88.00 South America, South Africa, Australasia/Air Mail fi = 7
n $25.00 International Surface Mail (lengthy, unreliable delivery] Fi=4,6,a
Name
Address
City State Zip
Country
Payment must be in US Funds drav\/n on a US Bank International Money
Order, or charge card.
n Payment Enclosed D VISA
□ MasterCard □ American Express
Acc't. No. Expires /
02-7
-J
J
■u
u
J
\\
}
^-\
-^